[Search for users] [Overall Top Noters] [List of all Conferences] [Download this site]

Conference bulova::decw_jan-89_to_nov-90

Title:DECWINDOWS 26-JAN-89 to 29-NOV-90
Notice:See 1639.0 for VMS V5.3 kit; 2043.0 for 5.4 IFT kit
Moderator:STAR::VATNE
Created:Mon Oct 30 1989
Last Modified:Mon Dec 31 1990
Last Successful Update:Fri Jun 06 1997
Number of topics:3726
Total number of notes:19516

3217.0. "AST's & XNextEvent ,XSendEvent" by BLKPUD::THOMASA (Wow I,ve got a colour ....) Thu Aug 16 1990 12:59

Hi all,
	Below is a C program for VMS which demonstrates the pitfalls of using 
XSendEvent from AST level and allowing XNextEvent to read the Xlib input 
queue when there are no events on it -- your code will hang at the XNextEvent
call for ever.
	The code fragment set up a window that receives button motion while
button1 is pressed and client message events. An ast is also set up to fire
an AST once every 10 seconds that writes 10 client message events and optionally a
Grvity Notify "dummy" event as well.
	Basically my problem is that as described above if XNextEvent is allowed
to read an empty queue it hangs for ever. even if you

	1. Send a dummy event from the AST
	2. regardless of what XSynchronize is set to
	3. regardless of how many times you press button 1 on the 
		mouse and move the mouse

But ...

	If you always test to see if the queue is empty and avoid using 
XNextEvent if it is the code works just fine.

	Before I qar this lot would any-one like to comment/try-out-the-code
in case I've missed something really obvious. 
	

CODE IS POSTED IN REPLY .1
--------------------------


	The code below offers you 3 options when you run it

$ run astsend_work
Allow XNextEvent to be called with 0 events on input queue
0-yes 1-no > 0						! question 1
Synchronize 1-yes 0-no > 1				! question 2
Send dummy non-client event from AST 1-yes 0-no > 1	! question 3

question 1

	Determines whether you allow XNextEvent to be called when there is 
nothing in the input queue

question 2

	Controls XSynchronize

question 3
	
	Determines whether you send a dummy "real event" (non-client message) 
from the AST routine



			THANKS 


				Andy Thomas (CSC Warrington UK)
T.RTitleUserPersonal
Name
DateLines
3217.1the codeBLKPUD::THOMASAWow I,ve got a colour ....Thu Aug 16 1990 13:03158
/* astsend_work.c   */
/*                  */
#define MAXLINE 100
#include <decw$include/Xlib.h>                                                  
#include <decw$include/X.h>                                                  
#include <decw$include/XAtom.h>                                                
#include <stdlib.h>
#include <stdio.h>
#include <descrip.h>
XEvent	dummy_event,myevent,got_event;
Display *disp1;
Window  wind1,root;
int	x,y,width,height,border_width,event_mask;
int     data,dial,mode,nq;
char file_spec[3];
FILE *file_ptr;
int k,status,len,val,sync,dummy; 
int ast_proc();
int bin_delay[2];
char 	prompt[40];
char    line[MAXLINE];

main()
{
int i,j;
/* ast info */
$DESCRIPTOR(delay, "0 ::10.00");  /*watch there's no space between */
				  /* "$DESCRIPTOR & ( "            */
/* window info */
x=20;
y=100;
width=400;
height=200;
border_width=60;

data=72;
dial=99;

/* contruct client event */

printf("Allow XNextEvent to be called with 0 events on input queue \n");
strcpy(prompt," 0-yes 1-no > ");
printf("\n%s",prompt);
len=getline(line,MAXLINE);
val=atoi(line);
strcpy(prompt,"Synchronize 1-yes 0-no > ");
printf("\n%s",prompt);
len=getline(line,MAXLINE);
sync=atoi(line);
strcpy(prompt,"Send dummy non-client event from AST 1-yes 0-no > ");
printf("\n%s",prompt);
len=getline(line,MAXLINE);
dummy=atoi(line);
myevent.type=ClientMessage;
myevent.xclient.display=disp1;
myevent.xclient.window=wind1;
myevent.xclient.data.l[0]=dial;
myevent.xclient.data.l[1]=data;
myevent.xclient.message_type=XA_INTEGER;
myevent.xclient.format=32;

dummy_event.type=GravityNotify;
dummy_event.xgravity.display=disp1;
dummy_event.xgravity.window=wind1;
dummy_event.xgravity.event=wind1;
dummy_event.xgravity.x=data;
dummy_event.xgravity.y=data;

/* open file for ast */ 
strcpy(file_spec,"TT:");
file_ptr=fopen(file_spec, "w");

/* convert delay to binary format */
if (((status=SYS$BINTIM(&delay,bin_delay)) &1)!=1)
	LIB$STOP(status);

/* set the timer */
if (((status=SYS$SETIMR(0,bin_delay,ast_proc,0)) &1)!=1)
	LIB$STOP(status);


/* open display connection */
disp1=XOpenDisplay(0);
	if (disp1==0)
		{
                printf("display is 0 folks \n");
                exit(1);
		}

/* blast up a window to receive events*/
root=XDefaultRootWindow(disp1);
wind1=XCreateSimpleWindow(disp1,root,x,y,width,height,border_width,             
CopyFromParent,ParentRelative);                                                 
event_mask=Button1MotionMask|ButtonPressMask|ClientMessage;
XSelectInput(disp1,wind1,event_mask);                                                                                
XMapWindow(disp1,wind1);                                                        
XFlush(disp1);
XSynchronize(disp1,sync);
mode=QueuedAlready;

/* loop forever */
printf("window id = %d \n",wind1);
nq=XEventsQueued(disp1,mode);
printf("Number queued = %d\n",nq);
for ( ; ; )
	{
	printf("\n");
	while (nq >=val) 
		{
		printf(".");
                XNextEvent(disp1,&got_event);
		nq=XEventsQueued(disp1,mode);
		}
	printf("\n");
	printf("Number queued = %d\n",nq);
	printf("sleeping .. \n");
	sleep(30);
	printf("waking up.. \n");
	printf("Number queued = %d\n",nq);
	nq=XEventsQueued(disp1,mode);
        }
	
XCloseDisplay(disp1);                                                           
}

int ast_proc()
{
/* this ast uses fprintf because this is a different channel for i/o */
/* than printf uses -- because device driver for terminal buffered i/o */
/* cannot multithread, if we delivered ast during a printf and then */
/* tried to use printf in the ast we'd get a recursive i/o error */
 
fprintf(file_ptr,"In ast sending 10 client events ... \n\n");
for (k=0 ;k<10 ;k++ ) 
	{
	XSendEvent(disp1,wind1,FALSE,ClientMessage,&myevent);
	}
	if (dummy == 1) 
		{
		XSendEvent(disp1,wind1,FALSE,ClientMessage,&dummy_event);
		fprintf(file_ptr,"sending dummy event from AST ... \n");
		}
XFlush(disp1);
nq=XEventsQueued(disp1,mode);
fprintf(file_ptr,"Number queued = %d\n",nq);
if (((status=SYS$SETIMR(0,bin_delay,ast_proc,0)) &1)!=1)
	LIB$STOP(status);
}


int getline(char *line, int max)
{
if (fgets(line,max,stdin)== NULL)
	return 0;
else
	return strlen(line);
}

3217.2PSW::WINALSKICareful with that VAX, EugeneThu Aug 16 1990 16:4814
RE: .1

I think your problem is in this line:

>    event_mask=Button1MotionMask|ButtonPressMask|ClientMessage;

This should read:

      event_mask=Button1MotionMask|ButtonPressMask;

You cannot mask ClientMessage events.  I don't know what happens if you OR
the symbol ClientMessage with the mask bits, but it probably isn't healthy.

--PSW
3217.3RE: .2BLKPUD::THOMASAWow I,ve got a colour ....Fri Aug 17 1990 05:5532
RE: .2
	Hi, thanks for your reply. I refer you to note 1351 in this conference
in which you also took part. Basically I agree about the use of ClientMessage
as a mask for XSelectInput, I used it here after reading note 1351.4

	If you remove the ClientMessage from the input mask the events from the
AST never get delivered at all !!! -- try it and see. This seems to contradict 
your statement that client messages are always delivered and can't be masked
out. this doesn't appear to be the case when they are delivered from the AST 
level

	For some reason using the event type value incorrectly as a mask value
to XSelectInput seems to alow these messages through.

	Further reading of note 1351 (reply 1351.7) seems to imply there is/was
a problem in the interaction of Xlib and the transport layer. 

	There was an entry in the QAR database decwindows-ift (node TRIFID)
qar number 3413 that describes this problem -- but this was closed on the 
assumption that the SSB kit had fixed the problem. This seems to be a false
assumption.

	Consequently I've opened a QAR in the V5 qar database (node TRIFID) 
qar number 3143, restating the problem and refering them to this note and
the previous qar.


			Yours

				Andy Thomas


3217.4tried on V5.4?STAR::HARDYFri Aug 17 1990 09:477
    
    
    	Have you been able to try your program on a V5.4 system?  If you can
    get onto a V5.4 system, that's where the Xlib/transport AST problems are
    corrected.
    
    			Sam
3217.5Try XSendEvent(...NoEventMask...)WILLET::frebKarl Freburger Object-based SystemsFri Aug 17 1990 22:2312
Instead of

>	XSendEvent(disp1,wind1,FALSE,ClientMessage,&dummy_event);

Try:

	XSendEvent(disp1,wind1,FALSE,NoEventMask,&dummy_event);

and don't select on ClientMessage events.  We use similar code in
an application that has to timeout of the event processing loop.

	 -karl freburger
3217.6hmm .... ?BLKPUD::THOMASAWow I,ve got a colour ....Wed Aug 22 1990 06:2212
Hi all,
	re: .4   I tried using VMS 5.4-4 ET , which I gather is NOT the latest
version of 5.4 you can get hold of. The problem was not fixed at this revision.
Do you know at what revision of VMS 5.4 the bug was fixed at ?

	re: .5    I also tried using NoEventMask in XSendEvent but this seemed 
to make no difference at all -- are you sure you were using XSendEvent from
AST level and allowing XNextEvent to be called when there were zero events
on the input queue ?


			Andy
3217.7PSW::WINALSKICareful with that VAX, EugeneWed Aug 22 1990 18:138
RE: .6

VMS Mandelbrot is a working example of sending ClientMessage events from ASTs
to "unstick" DECwindows event processing.  It does its event processing
through the Toolkit (XtNextEvent, etc.), but the mechanics is the same if you
use pure X (vs. Xt).

--PSW
3217.8re: .7BLKPUD::THOMASAWow I,ve got a colour ....Tue Aug 28 1990 09:1711
Hi,
	Hmm .. I'm not sure the mechanics are the same, the sources show that 
XtNextEvent calls XtAppNextEvent which itself uses a call to XPending to test
whether there are any unprocessed events on the event queue BEFORE allowing
XNextEvent to be called.

	In other words using the XtNextEvent avoids calling XNextEvent with 
0 events on the queue which seems to be the crux of my problem

				
			Andy
3217.9PSW::WINALSKICareful with that VAX, EugeneWed Aug 29 1990 14:306
RE: .8

Is there a reason that you can't use the same technique (call XPending before
calling XNextEvent)?

--PSW
3217.10Am doing at the moment.BLKPUD::THOMASAWow I,ve got a colour ....Thu Aug 30 1990 06:357
Hi,
   re:.9. I am using this method for now, and will continue to do so until I can
get my paws on a SSB version of VMS 5.4 where this problem is supposed to be 
fixed, anyway thanks for your input.


			Andy
3217.11good workaround for 5.3-1BLKPUD::THOMASAWow I,ve got a colour ....Fri Sep 14 1990 06:5742
Hi all,
	I.m still waiting to test this problem on the SSB vms 5.4, but in the 
meantime I've discovered a workaround that is quite neet, The book Introduction
to the X Window System by Oliver Jones has some example code in it for 
processing events from multiple displays on a unix machine. This method relies
on using the unix SELECT call which is roughly equivilant to the vms $WAITFR.
	Using $WAITFR on the ConnectionNumber, seems to work quite nicely see 
code extract below

/* the main loop from previous examples now becomes */ 

for ( ; ; )
{

nfds=ConnectionNumber(disp1);
printf("connection number %d\n",nfds);

got_one=0;
while (!got_one)
	{
	while (XEventsQueued(disp1,mode)>0){
        XNextEvent(disp1,&got_event);
	printf(".");
	got_one=1;
	continue;
	}
	if (((status=SYS$CLREF(nfds))&1)!=1) /* waits here until event arrives */ 
 		LIB$STOP(status);      /* including client messages from user */
					/* AST's */

	XFlush(disp1);
	/* background processing here if wanted */
	printf("waiting for efn \n");
	if (((status=SYS$WAITFR(nfds)) & 1)!=1)
		LIB$STOP(status);
	}
} /* end of for loop */
XCloseDisplay(disp1);                                                           
} /* main */


 
3217.12PSW::WINALSKICareful with that VAX, EugeneFri Sep 14 1990 16:069
RE: .11

select() on bsd Unix is actually closer to $WAITM than $WAITFR.

Is the correspondence between connection numbers and event flags documented
anywhere?  I suspect that it's merely an artifact of the current VMS Xlib
implementation.  I wouldn't depend on it, if it were my application.

--PSW
3217.13DECWIN::FISHERLocutus: Fact or Fraud?Mon Sep 17 1990 18:469
That will break in V5.4.  Connection number is used for two things in X:
1) to select on, and (2) as a unique integer to identify the connection.  We
use the same event flag for all connections, so 2 was broken.  In addition,
select is really not quite the same.  You can't depend on the $WAITFR on the
event flag, since there will also be an AST fired off at the same time, and
in that AST, the event flag might be cleared.  Anyway, since you can't count
on 1 anyway, and since we needed (2) badly, we changed the behavior to (2).

Burns
3217.14more info on .13BLKPUD::THOMASAWow I,ve got a colour ....Wed Sep 19 1990 13:2349
Hi all,
       re .13, Burns Fisher has been kind enough to mail me an expaned 
explanation of .13, I post it here for all who might be interested, I also
see that note 1351 and 2292 in this conference have been discussing what appears
to be the same/similar problem .I will post the results of my tests on VMS 5.4 
SSB to see if the problem is at last cured , I should be able to do this
sometime next week.

				Andy

.13 expanded explanation :-


Sure.  dpy->connection (is that the right name?) was designed to hold the unix
file id for the network connection.   The problem is that in Ultrix, the file 
id is a description of everything about a connection:  both the connection
itself and the i/o that is going on.  That means that you can write/read to a
file/connection using the file id and then check to see if that write/read is
done by doing a Unix Select statement on the file id.

In VMS, we allow multiple I/Os to be queued to the same connection.  That means
that the file id (which we call the channel) is no good for waiting on an I/O.
You need other stuff like an event flag.

So the question is, what do we put in dpy->connection?  Initially, we put
the event flag that was being used on the connection.  This allows someone
to do $WAITFR on it and get a behavior *similar* to Select.  There are two
problems with this, both relating to the fact that event flags are not unique.
The first is that if you do $WAITFR on the event flag, and the $WAITFR returns,
you can't guarantee that there was really IO on the connection.  It might have
been triggered by something else.

The second problem is that some programs need a unique index with which to
refer to a connection.  In Unix, the file id is guaranteed to be a small, 
unique number (small is less than the maximum files that a process can open,
usually less than 100).  Thus a lot of programs use dpy->connection as a unique
id number.  It does not work with an event flag.  The same ef is used for all
connections.

Since (1) the event flag really does not work right when used with WAITFR to
simulate SELECT, and (2) since the Xlib spec specifically calls this os 
dependent, but does not define it for non-POSIX/UNIX systems, we changed it to
a more useful value: a unique number which we assign to the connection, but
which has nothing to do with the I/O. 

Does that help?

Burns

3217.155.4 ssb testsBLKPUD::THOMASAWow I,ve got a colour ....Mon Sep 24 1990 06:4020
Hi all,
	Ok so I've installed vms 5.4 SSB and here are the results of the tests
in reverse order:-

1. using $WAITFR still seems to work just fine, contradicting the information in
reply .14 & .13, can you comment in this Burns ? Were the changes to the 
ConnectionNumber macro implemented in VMS 5.4 SSB ? the evidence would seem to
suggest not.

2. Using XNextEvent as in reply .0 shows some improvement, client messages ARE 
still ignored when they are sent -- BUT when a real event such as a button press
occurs all the queued events (real and from XSendEvent) get read. This is an 
improvement in the situation but it still strikes me as being incorrect 
behaviour that client events sent from an AST are ignored by XNextEvent until
a 'real' event is sent.


		What do you all think ?

			Andy
3217.16PSW::WINALSKICareful with that VAX, EugeneMon Sep 24 1990 14:483
I think it's more likely that you're botching your XSendEvent call somehow.

--PSW
3217.17howdy rowdyBLKPUD::THOMASAWow I,ve got a colour ....Tue Sep 25 1990 08:5212
re: .16
	I'd like to think I was botching my XSendEvent call, then I could forget
all about this and go and play with other stuff still.....

	I think this XSendEvent is ok becuase the events sent like this do get
read ok eventually and do show up before reading to calls such a XPending and
XEventsQueued. The code is in reply .1 and I am open to correction

		Thanks

			Andy
		
3217.18don't count on it to continue to workDECWIN::JACKIEnews() { *Iraq+=*Kuwait; free(Kuwait); num_countries--; }Fri Sep 28 1990 12:1017
The reason your code hasn't broken (yet) is that when we put the change in
that Burns described, we pointed the ConnectionNumber to an additional
field in the display structure holding the efn.  We thought that there might
be some people who had hacked around as you did and that it would break 
their programs.  But this doesn't mean that it will stay this way forever.
If you want to use this risky unsuported feature, you might want to reference
the display field directly as it probably has the highest chance of continuing
to work.

Jackie

From Xlib.h:
#ifdef VMS
#define ConnectionNumber(dpy)   ((dpy)->efn)
#else
#define ConnectionNumber(dpy)   ((dpy)->fd)
#endif /* VMS */
3217.19Warning! Danger Will Robinson!DECWIN::FISHERLocutus: Fact or Fraud?Fri Sep 28 1990 14:435
From what Jackie says, that implies that if you recompile it will break.
However, it just occurred to me that if we use event flag number 1, this may
work for the first display even then.

Burns
3217.20Hmm still broken though ...BLKPUD::THOMASAWow I,ve got a colour ....Mon Oct 01 1990 09:3534
Dear Jackie and Burns,
			Interesting as the ConnectionNumber macro and using 
$WAITFR saga is, the main point of all this is that using XSendEvent from a
user AST completely kills off XNextEvent so that it never works again !!!!

	I don't want to tell people to "hack around" using $WAITFR and the 
ConnectionNumber stuff, I want to be able to tell them "yeah sure use 
XSendEvent from your AST and XNextEvent will respond to it" BUT .. no it doesn't

	The problem is still here at VMS 5.4, although calling XEventsQueued
tells you that you have more and more Events queued up from the XSendEvent in 
the AST. XNextEvent sits there stubornly, in my latest tests I can't get the 
damn thing to come back no matter what I throw at it !

	Previous notes in this conference have stated the problem is due to an
interaction between XLIB and the Transport Layer (James N Synge note 2292
amoung others) This bug is reported in this conference to be fixed at VMS 5.4 
which quite clearly IS NOT the case.

	My dilema is then do I raise a priority 1 SPR or even a CLD (QAR already
done)  -- yes some of my customers are getting nervous enough for a CLD.
Obviously you guys know all about this problem note 2292.1 (James Synge) says it
is definately NOT fixed until after VMS 5.4.

	If then you tell me I have to wait till 5.4-1 or whatever to see this 
fixed so be it. If you tell me it should be fixed now I'll SPR or what-ever 
right now. The thing is I don't want to bombard you guys with SPR/CLD's un-
necessarily if the fix is on the way. 


		What do yer think


			Andy
3217.21I did re-compile by the wayBLKPUD::THOMASAWow I,ve got a colour ....Mon Oct 01 1990 09:435
    Hi again,
    	    Oh, I forgot to mention -- yes I did recompile and link --
    $WAITFR still works ok. But as I said this is of secondary importance.
    
    		Andy
3217.22DECWIN::FISHER&quot;I like my species the way it is&quot; &quot;A narrow view...&quot;Mon Oct 01 1990 14:3113
Sorry if we got into a rathole...

If James said it is not fixed in VMS V5.4, then the fix is probably in DW V3.
Unfortunately for all of us (but luckily for the Portland office) James decided
to leave Central Eng. for the field.  I know that we was working on transport
bugs and believed that he had finished them all before he left.

You might keep watch for the IFT version of DW V3 and make sure the fix is
there.  You may also be able to work with CSSE et al to get the fix early.  You
probably know more about that mechanism than I do.

Burns