[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

1239.0. "details needed on async input" by CURIE::FORBES (Windows are panes in the glass) Mon Aug 07 1989 19:26

Can someone drop a simple test program as a reply that demonstrates the use
of XSelectAsyncInput() on Ultrix if you have one applicable to the following
scenarios?

If I go off in to never-never land drawing graphics on the display, and I want
to stop short if the user enters Control-C.

If I go off in to never-never land munching numbers and wish to be interrupted
in the same way.


I have had no luck with a simple test program... a benchmark that runs for a
while, testing a global variable every so often.

Is XSelectAsyncInput() really asynchronous?  Does the server send a special
protocol message to the client or do I need to be extracting events with
XNextEvent to see it?

T.RTitleUserPersonal
Name
DateLines
1239.1FLUME::dikeTue Aug 08 1989 09:269
I don't have any code handy, but here is how it works:
You have to XSelectInput any events that you XSelectAsyncInput
Your handler has to XNextEvent, or something equivalent, to extract
the event from the queue.

XSelectAsyncInput is nothing but an addition to Xlib.  No protocol
is generated by the async calls.
				Jeff

1239.2how can do?CURIE::FORBESWindows are panes in the glassTue Aug 08 1989 12:326
	So, the bottom line is there is no way of interrupting the tasks
that are being performed as descibed in .0?  If XSelectAsyncInput is Xlib only,
then there can be no provision by which the server can be set up to send a
protocol message back to the client that will then use a local op sys mechanism
for interrupting/waking up the client asynchronously...???

1239.3FLUME::dikeTue Aug 08 1989 13:305
The whole point of it is that it interrupts the process out of
whatever it was doing.  If all you want is to have the server
interrupt you, then send a ClientMessage event to yourself.
				Jeff

1239.4CURIE::FORBESWindows are panes in the glassTue Aug 08 1989 15:388
The following reply is a test program.  It runs OK as is, but is
uninterruptable.  If line 190 is uncommented, control-C should interrupt
it.  Instead the application goes 'on hold' until button clicks or key
events are received in the window.  Any ideas? ...

incidentally, dbx likes to stop with 'I/O possible', referring to the
FASYNC being set on the descriptor for SIGIO.

1239.5async.cCURIE::FORBESWindows are panes in the glassTue Aug 08 1989 15:40395
	/*-----------------------------------------------------
	  	test XSelectAsyncInput() call...

		test drawing lines and segments in batch.
		For oblique lines, the length of the line
		is the equivalent calculated as the radius
		of a circle...

		argv[1] = starting length
		argv[2] = ending length
		argv[3] = increment

		mouse button 1 - vertical lines
		mouse button 3 - horizontal lines
		mouse button 2 - diagonal lines - direction
			determined by click-drag-release.

		modify the comments at line 329+ to draw
		lines or segments.
	  -----------------------------------------------------*/

#include <stdio.h>
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <math.h>

#include <signal.h>

#include <sys/types.h>
#include <sys/times.h>
#include <sys/timeb.h>
#include <sys/time.h>
#include <sys/resource.h>

#define MILLION 1000000.0

#ifndef HZ
#define HZ 60.0
#endif

#define STRING	"Lines Test"
#define BORDER	1
#define FONT	"vrb-25"

#define CVT (3.1415927/180.0)

#define ABS(a) ((a) >= 0 ? (a) : -(a))

float  SCWetime(), SCWctime();

/* This structure forms the WM_HINTS property of the window,
 * letting the window manager know how to handle this window.
 * See Section 9.1 of the Xlib manual.
 */

XWMHints	xwmh = {
    (InputHint|StateHint),	/* flags */
    True,			/* input */
    NormalState,		/* initial_state */
    0,				/* icon pixmap */
    0,				/* icon window */
    0, 0,			/* icon location */
    0,				/* icon mask */
    0,				/* Window group */
};

XSegment  segments[5000];
int       nsegments;

Display    *dpy;		/* X server connection */
Window      win;		/* Window ID */
static int  ctrl_c_cancel;

void  async_input_handler();

	/*--------------------------------------------------------------*
	 *	async input handler proc				*
	 *--------------------------------------------------------------*/


void async_input_handler (bs)
     unsigned long  bs;
{
  XEvent  event;
  static XComposeStatus  kbd_status;
  KeySym      key_sym;
  char        key_ascii;

  if (XCheckMaskEvent (dpy, KeyPressMask, &event))
    {
      switch (event.type)
	{
	case KeyPress:
	  if (XLookupString (&event, &key_ascii, 1, &key_sym, &kbd_status))
	    if (key_ascii == 3)
	      {
		printf ("Ctrl-C interrupt!\n");
		ctrl_c_cancel = True;
	      }
	  break;
	  
	default:
	  printf ("	ack!!!\n");
	  break;
	}
    }
}


	/*--------------------------------------------------------------*
	 *	main							*
	 *--------------------------------------------------------------*/


main (argc,argv)
     int argc;
     char **argv;
{
  GC          gc;		/* GC to draw with */
  XFontStruct *fontstruct;	/* Font descriptor */
  unsigned long fth, pad;	/* Font size parameters */
  unsigned long fg, bg, bd;	/* Pixel values */
  unsigned long bw;		/* Border width */
  XGCValues   gcv;		/* Struct for creating GC */
  XEvent      event;		/* Event received */
  XSizeHints  xsh;		/* Size hints for window manager */
  char       *geomSpec;	/* Window geometry string */
  XSetWindowAttributes xswa;	/* Temporary Set Window Attribute struct */
  int	      scr_num, i, j, k, start_x, start_y, end_x, end_y, e_x, e_y;
  Screen     *scr;
  int         dfd, dfd_mask, nfound, pressing = False;
  float       angle[38], sina[38], cosa[38];
  int         cx, cy, rx, ry;
  XPoint      points[38];
  char       *x_debug;
  int         x1, y1, x2, y2;
  int         repeat, batchcount;
  float	      xx, yy, rr;
  float       cpu_start, cpu_end, elp_start, elp_end;
  XComposeStatus  kbd_status;
  KeySym      key_sym;
  char        key_ascii;


  if ((dpy = XOpenDisplay(NULL)) == NULL)
    {
      fprintf(stderr, "%s: can't open %s\en", argv[0], XDisplayName(NULL));
      exit(1);
    }

  fg = WhitePixelOfScreen (DefaultScreenOfDisplay (dpy));
  bg = BlackPixelOfScreen (DefaultScreenOfDisplay (dpy));

  xsh.flags = (PPosition | PSize);
  xsh.height = 750;
  xsh.width = 900;
  xsh.x = 25;
  xsh.y = 25;

  win = XCreateSimpleWindow(dpy, DefaultRootWindow(dpy),
			    xsh.x, xsh.y, xsh.width, xsh.height,
			    bw, bd, bg);

  XSetStandardProperties(dpy, win, STRING, STRING, None, &argv, argc, &xsh);
  XSetWMHints(dpy, win, &xwmh);

  xswa.colormap = DefaultColormap(dpy, DefaultScreen(dpy));
  xswa.bit_gravity = CenterGravity;
  XChangeWindowAttributes(dpy, win, (CWColormap | CWBitGravity), &xswa);

  gcv.function = GXxor;
  gcv.plane_mask = 0xFF;
  gcv.foreground = fg;
  gcv.background = bg;
  gc = XCreateGC (dpy, win,
		  (GCFunction | GCPlaneMask | GCForeground | GCBackground),
		  &gcv);

/*....*/
  XSynchronize (dpy, True);
/*....*/

  XSelectInput (dpy, win,
		ButtonPressMask | ButtonReleaseMask | KeyPressMask);
/*....
  XSelectAsyncInput (dpy, win, KeyPressMask,
		     async_input_handler, NULL);
....*/

  XMapWindow(dpy, win);

  XFlush (dpy);

  printf ("sleeping...\n");
  sleep (3);
  printf ("...done.\n");

  XSetInputFocus (dpy, win, RevertToNone, CurrentTime);

  XClearWindow(dpy, win);

  gcv.function = GXxor;
  gcv.foreground = fg;
  XChangeGC (dpy, gc, GCForeground | GCFunction, &gcv);

  for (j = 0; j <= 36; j++)
    {
      angle [j] = j * 10 * CVT;
      sina [j]  = sin (angle [j]);
      cosa [j]  = cos (angle [j]);
    }

  ctrl_c_cancel = False;

  while (1)
    {
      XNextEvent (dpy, &event);
      switch (event.type)
	{
	case KeyPress:
	  printf ("key press!\n");
	  if (XLookupString (&event, &key_ascii, 1, &key_sym, &kbd_status))
	    if (key_ascii == 3)
	      {
		printf ("Ctrl-C interrupt!\n");
		ctrl_c_cancel = True;
	      }
	  break;
	case ButtonPress:
	  if (!pressing)
	    {
	      pressing = True;
	      start_x = event.xbutton.x;
	      start_y = event.xbutton.y;
	    }
	  else
	    {
	      printf ("\n");
	      pressing = False;
	    }
	  break;
	case ButtonRelease:
	  if (pressing)
	    {
	      pressing = False;

	      repeat = 8;
	      batchcount = 250;
	      nsegments = repeat * batchcount;

	      end_x = event.xbutton.x;
	      end_y = event.xbutton.y;

	      for (k = atoi (argv [1]);
		   k <= atoi (argv [2]);
		   k += atoi (argv [3]))
		{

		  if (ctrl_c_cancel)
		    {
		      ctrl_c_cancel = False;
		      break;
		    }

		  if (event.xbutton.button == Button2)
		    {
		      printf ("oblique...  ");

		      /*....determine lengths of sides of triangle....*/

		      xx = (float) end_x - start_x;
		      yy = (float) end_y - start_y;
		      rr = (float) sqrt (xx*xx + yy*yy);

		      /*....normalize xx and yy....*/

		      xx = xx/rr;
		      yy = yy/rr;

		      /*....calculate the ending point of the line....*/

		      e_x = start_x + xx * k;
		      e_y = start_y + yy * k;
		    }
		  else if (event.xbutton.button == Button1)
		    {
		      printf ("vertical...  ");
		      e_x = start_x;
		      e_y = start_y + k;
		    }
		  else   /* MB3 */
		    {
		      printf ("horizontal...  ");
		      e_x = start_x + k;
		      e_y = start_y;
		    }

		  x1 = start_x;
		  x2 = e_x;
		  y1 = start_y;
		  y2 = e_y;

		  elp_start = SCWetime (0.0);
		  cpu_start = SCWctime (0.0);

		  for (i = 0; i < repeat; i++)
		    {
		      for (j = 0; j < batchcount; j++)
			{
			  segments [i * batchcount + j].x1 = x1 + j;
			  segments [i * batchcount + j].y1 = y1;
			  segments [i * batchcount + j].x2 = x2 + j;
			  segments [i * batchcount + j].y2 = y2;
			}
		      x1 += 3;
		      x2 += 3;
		      y1 += 1;
		      y2 += 1;
		    }

		  for (i = 0; i < 100; i++)
/*...*/
		    XDrawSegments (dpy, win, gc, segments, nsegments);
/*....*/

/*...
		    XDrawLines (dpy, win, gc, segments, 2*nsegments,
		    		CoordModeOrigin);
...*/

		  cpu_end = SCWctime (cpu_start);
		  elp_end = SCWetime (elp_start);

		  printf ("cpu: %5.3f  elp: %5.3f   (len=%d)\n",
			  cpu_end, elp_end, k);

		}   /*...k loop...*/

	    }
	  break;
	default:
	  printf ("%c%c%cUnknown Event!\n", 7, 7, 7);
	  break;
	}
    }
}


float SCWctime (last)
     float last;
{
  struct rusage	me,kids;
  static int	first_time = 1;
  static double	first_cpuse = 0.0;
  double	cpuse;

  getrusage (RUSAGE_SELF,	&me);
  getrusage (RUSAGE_CHILDREN,	&kids);
  cpuse = me.ru_utime.tv_sec   + me.ru_utime.tv_usec/MILLION   +
/*
	  me.ru_stime.tv_sec   + me.ru_stime.tv_usec/MILLION   +
*/
	  kids.ru_utime.tv_sec + kids.ru_utime.tv_usec/MILLION;
/*
	  kids.ru_stime.tv_sec + kids.ru_stime.tv_usec/MILLION;
*/
  if (first_time)
    {
      first_cpuse = cpuse;
      first_time = 0;
    }
  return (cpuse - first_cpuse - last);
}



float SCWetime (last)
     float last;
{
  struct timeb	elp_time;
  static int	first_time = 1;
  static double	first_elapsed = 0.0;
  double	elapsed;

  ftime (&elp_time);
  elapsed = elp_time.time + elp_time.millitm/1000.0;
  if (first_time)
    {
      first_elapsed = elapsed;
      first_time = 0;
    }
  return (elapsed - first_elapsed - last);
}

1239.6FLUME::dikeTue Aug 08 1989 19:438
It seems to work for me.  I ran it with the XSelectAsyncInput call
uncommented, and the async handler got called whenever I pressed
a key, just like I would expect.

Incidentally, "ignore 23" will cause dbx not to stop whenever a
SIGIO comes in.
				Jeff

1239.7Xlib bugCURIE::FORBESWindows are panes in the glassThu Aug 10 1989 12:403
This was an Xlib bug.  Jeff found a solution and submitted a QAR and a
patch.  Should appear in the next release.