[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

2244.0. "XSendEvent filtered out by toolkit?" by NRMACP::WATSON (Because Daddy says so...thats why) Fri Feb 09 1990 11:18

    Do the DECwindows toolkit and the window manager not allow Sendevent
    events to be passed to the application ?
    
    I have an application which sends a button event to the window which 
    contains the pointer.  This works when the pointer is in a window of a 
    "pure" X application, but does not work when the DEC window manager is
    running, and also does not work when the pointer is in a toolkit widget
    window.  Is my suspicion correct, and if so is there any way to
    override this ?
    
    -- Rob
T.RTitleUserPersonal
Name
DateLines
2244.1Post some codeDECWIN::KLEINFri Feb 09 1990 12:537
>    Do the DECwindows toolkit and the window manager not allow Sendevent
>    events to be passed to the application ?

How are you determining the destination window ID?  Please post your
XSendEvent code.

-steve-
2244.2Code as requestedNRMACP::WATSONBecause Daddy says so...thats whyMon Feb 12 1990 12:56326
        
/* Copyright 1988 by Digital Equipment Corporation, Maynard, Massachusetts.
 * 
 *                         All Rights Reserved
 * 
 */

/*

 * program  : multi.c
 * Author   : Rob Watson NRMACP::WATSON  @BIO 
 *	      DTN 841-3115
 * Date     : February 1990

    Program written to test capability of handling multiple displays with a
    single mouse (and keyboard) with standard X server, requiring no special
    hardware.

    Not yet fully working, just an experimental hack.

    Usage:  Run the program on the "master" workstation (the one whose
	mouse will be used), enter the name of the "slave" display.
	A small window will appear in top right of each display.
	Click MB3 on this window to toggle the "active" display (i.e. the
	one the mouse is driving).  When the slave display is active, the
	cursor will change and the pointer will track the pointer on the 
	master.  MB1 and MB2 clicks SHOULD be passed through to the 
	applications.

    Problems:

	"Pure" X programs work OK when no window manager is running.

	When the DECwindows window manager is running, events do not get sent
	to the application.  Same for Motif WM.  The HPWM sometimes works.

	Events do not get passed to DECwindows toolkit or Motif applications.

	I have not yet tried to pass keyboard events, but this should be trivial
	once the above issues are sorted.


 */


#include "decw$include:Xlib.h"
#include stdio

Display *CurrentDisp;				/* display currently active */
Display *disp1, *disp2;				/* The two displays */

Screen  *scrp1, *scrp2;				/* The only screen on them */
int	scn1, scn2;				/* Default screen number */

Window  CurrentWin;
Window	win1, win2;				/* Top level windows */
Window	root1, root2;				/* root windows */

unsigned xdim = 100, ydim = 100;		/* Of window */
unsigned white1, white2;			/* Pixel value */
unsigned black1, black2;			/* Colour */
XSetWindowAttributes winat1,winat2;		/* Window attributes */
unsigned x,y;					/* pointer coords */
unsigned status;

Window	pointer_root, pointer_window, child;
int	root_x, root_y, pointer_x, pointer_y;

unsigned int pointer_mask;

main(argc,argv)
char *argv[];
	{
	XEvent evt;
	int button = 0;
	unsigned lx, ly;			/* Last reported pointer */
	char ch;				/* Character typed */
	Cursor cursor1, cursor2, xcursor1, xcursor2;


	/* Initialise */

	startup(argc, argv);

	/* do this to display the windows */
	XFlush (disp1);
	XFlush (disp2);

	xcursor1 = XCreateFontCursor (disp1, 0);
	xcursor2 = XCreateFontCursor (disp2, 0);
	cursor1  = XCreateFontCursor (disp1, 38);
	cursor2  = XCreateFontCursor (disp2, 38);

	printf("DISPLAY 1 CURRENT\n");
	CurrentDisp = disp1;
	CurrentWin  = win1;


	XWarpPointer	(disp1, None, win1, 0, 0, 100, 100, 0, 0);
	XWarpPointer	(disp2, None, win2, 0, 0, 100, 100, 0, 0);
	XDefineCursor	(disp1, win1, xcursor1);
	XDefineCursor	(disp2, win2, cursor2);


	for (;;) {
	/* only look at events in disp1 */
		XNextEvent(disp1, &evt);

		if ( ((evt.type == ButtonPress) || (evt.type == ButtonRelease))
		    && (evt.xbutton.window == win1) )
		    {
			button = evt.xbutton.button;
			printf("ButtonPress/release in window 1 Button = %d \n", button);

			/* use button 3 to toggle display */
			if (button == 3)
			{
			if (   (CurrentDisp == disp1)
			    && (evt.type == ButtonPress) )
			    /* only for button press, or just switches back */
			    {
				printf ("Current Display = 2\n");
				CurrentDisp = disp2;
				CurrentWin  = win2;
				/* change cursors */
				XDefineCursor (disp1, win1, cursor1);
				XDefineCursor (disp2, win2, xcursor2);
				XWarpPointer (disp1, None, win1, 0, 0, 100, 100, 0, 0);
				XWarpPointer (disp2, None, win2, 0, 0, 100, 100, 0, 0);

				printf("Grabbing pointer now...\n");
				XGrabPointer
				    (disp1, win1, 
				    True,
				    winat1.event_mask,
				    GrabModeAsync,
				    GrabModeAsync,
				    None,	    
				    cursor1,
				    CurrentTime);
			    }
			/* if button 3 and disp2 current */
			else if (   (CurrentDisp == disp2)
			    && (evt.type == ButtonPress) )
			    {
				printf ("Current Display = 1\n");
				CurrentDisp = disp1;
				CurrentWin  = win1;
				/* change cursors */
				XDefineCursor (disp1, win1, xcursor1);
				XDefineCursor (disp2, win2, cursor2);
				XWarpPointer (disp1, None, win1, 0, 0, 100, 100, 0, 0);
				XWarpPointer (disp2, None, win2, 0, 0, 100, 100, 0, 0);

				printf("UNGrabbing pointer now...\n");
				XUngrabPointer
				    (disp1,
				    CurrentTime);

			    }
			}
			else if (CurrentDisp == disp2)
			    /* CHECK FOR BUTTON 1 and 2 */
			    {
				printf ("Sending Button event to disp 2\n");

				status = XQueryPointer
					(disp2,
					root2,
					&pointer_root,
					&pointer_window,
					&root_x,
					&root_y,
					&pointer_x,
					&pointer_y,
					&pointer_mask );

				/* translate to pointer_window coordinates */
				XTranslateCoordinates
					(disp2,
					root2,
					pointer_window,
					root_x, root_y,
					&pointer_x, &pointer_y,
					&child );


				evt.xbutton.display = disp2;
				evt.xbutton.window = pointer_window;
                                evt.xbutton.root = root2;
				evt.xbutton.subwindow = pointer_window; /*??*/
				evt.xbutton.x = pointer_x;
				evt.xbutton.y = pointer_y;
				evt.xbutton.x_root = root_x;
				evt.xbutton.y_root = root_y;

				status =
				XSendEvent (CurrentDisp, 
					   /*  PointerWindow, */
					    pointer_window,
					    1,	    /* propagate ?? */
					    ~NoEventMask,
					    &evt);
				/* printf ("status=%d\n",status); */
			    }

		    }
		else if (   (evt.type == KeyPress) 
			 && (evt.xkey.window == win1) )  
		    {
			XLookupString(&evt, &ch, 1, NULL, NULL);
			if (ch == '\3') return;	/* Control-C */
			if (ch == '\031') return; /* Ctrl-Y */
		    }

    /* track cursor motion on display 2 */
		else if (   (evt.type == MotionNotify) 
			&&  (CurrentDisp == disp2) )
		    {
			x = evt.xmotion.x_root;
			y = evt.xmotion.y_root;

			/* printf("Motion Notify %d %d\n",x,y); */
			/* warp the mouse */
			XWarpPointer (disp2, None, root2, 0, 0, 0, 0, x, y);
			/* send the event to the current display */
			status =
			XSendEvent (CurrentDisp, 
				    PointerWindow, 
				    1,	    /* propagate ?? */
				    ~NoEventMask,
				    &evt);
/*			printf ("status=%d\n",status); */
		    }
		else 
		    {
/*			printf ("sending some event\n"); */
			/* send the event to the current display */
			XSendEvent (CurrentDisp, 
				    PointerWindow, 
				    1,	    /* propagate ?? */
				    ~NoEventMask,
				    &evt);
			
		    }

		}
	}


/* Startup routine, processes arguments and initialises window */

startup(argc,argv)
char *argv[];
	{
	char *dispnm1 = 0;			/* Name of display 1 */
	char dispnm2[20];			/* Name of display 2 */

	/* Open the displays.*/

	disp1 = XOpenDisplay(dispnm1);
	scrp1 = DefaultScreenOfDisplay(disp1);
	scn1  = DefaultScreen(disp1);

	printf ("Display  NODE::SERVER.SCREEN?");
	scanf ("%s", &dispnm2);
	printf ("\nSlave display on %s\n", dispnm2);

	disp2 = XOpenDisplay(dispnm2);
	scrp2 = DefaultScreenOfDisplay(disp2);
	scn2  = DefaultScreen(disp2);

	/* Synchronize with server for  debugging */
	XSynchronize(disp1, 1);
	XSynchronize(disp2, 1);

	root1 = DefaultRootWindow(disp1);
	root2 = DefaultRootWindow(disp2);

	/* Create the top-level window */

	black1 = BlackPixel(disp1, scn1);
	white1 = WhitePixel(disp1, scn1);
	winat1.background_pixel = black1;
	winat1.border_pixel = white1;
	winat1.event_mask = 
	   Button1MotionMask | Button2MotionMask | Button3MotionMask |
	   ButtonPressMask | ButtonReleaseMask | 
	   PointerMotionMask | KeyPressMask  ;

	win1 = XCreateWindow(disp1, 		/* Display */
			    root1,		/* parent */
			    0, 0,		/* x, y */
			    xdim, ydim, 2,	/* width, height, border */
			    0, InputOutput,	/* depth, class */
			    DefaultVisual(disp1, scn1),
			    CWBackPixel|CWBorderPixel|CWEventMask,
			    &winat1);		/* Mask and attributes */
	XStoreName (disp1, win1, "Window 1");

	black2 = BlackPixel(disp2, scn2);
	white2 = WhitePixel(disp2, scn2);
	winat2.background_pixel = black2;
	winat2.border_pixel = white2;
	winat2.event_mask = 
	   Button1MotionMask | Button2MotionMask | Button3MotionMask |
	   ButtonPressMask | ButtonReleaseMask | 
	   PointerMotionMask | KeyPressMask  ;

	win2 = XCreateWindow(disp2, 		/* Display */
			    root2,		/* parent */
			    0, 0,		/* x, y */
			    xdim, ydim, 2,	/* width, height, border */
			    0, InputOutput,	/* depth, class */
			    DefaultVisual(disp2, scn2),
			    CWBackPixel|CWBorderPixel|CWEventMask,
			    &winat2);		/* Mask and attributes */
	XStoreName (disp2, win2, "Window 2");

	/* Map the window to start the event cycle */

	XMapRaised(disp1, win1);
	XMapRaised(disp2, win2);

}
    
2244.3PSW::WINALSKICareful with that VAX, EugeneMon Feb 12 1990 13:003
Why are you saying "~NoEventMask" in your XSendEvent calls?

--PSW
2244.4Mixed-up display IDs?DECWIN::KLEINMon Feb 12 1990 13:349
(1) I think that the display in the event and and the XSendEvent call must
be the same.  Are they?

(2) Assuming you are trying to send a button event, you should pass
ButtonPressMask (or whatever) as the mask field.  It is not clear
what setting all the mask bits will do.  Some servers will reject
this as having MBZ bits set.

-steve-
2244.5Programmer error!NRMACP::WATSONBecause Daddy says so...thats whyWed Feb 14 1990 07:428
    Problem solved.  I misunderstood the use of XQuery Pointer, which only
    returns the first level child containing the pointer, not the "leaf"
    window.  Just making the XTranslateCoordinates recursive to find the
    bottom level window containing the pointer fixed it.  A few problems
    remain, but its nearly there.
    
    -- Rob
    
2244.6Checl for WM_STATE property to find client windowOPHION::MIKEYMike YangWed Feb 14 1990 12:037
    If you're trying to find the actual client window (rather than the
    window manager's "frame" window), to be correct you should check for
    the existence of a WM_STATE property.  Windows with such properties are
    client windows.  ICCCM-compliant window managers place these properties
    on client windows.  The XUI window manager may or may not do this,
    depending on the version.  The UWS 2.2 version of dxwm and later
    certainly do.
2244.7Not in XUISTAR::CYPRYCHWed Feb 14 1990 13:377
    
    Checking for WM_STATE property to find a client window
    will not work for XUI window manager on VMS.  Also, it
    will not work for override-redirect windows -- regardless
    of window manager.
    
    Nancy