[comp.windows.x] Problem receiving events

montnaro@spyder.crd.ge.com (Skip Montanaro) (11/29/90)

I have a simple application written on a Sun-4 using the HP widgets that
connects to Sun's OpenWindows 2.0 server.  (I realize there are potential
problems running the HP widgets (R3-compliant?) against an R4-compliant
server.)  I am having trouble receiving events I select. Here is the
structure of the widget tree:

	XwRowColWidgetClass (outer_win - window 900005)
	    XwWorkSpaceWidgetClass (wkspc_win - window 900006)

I get the Xlib window id for both widgets and use XSelectInput to set the
event masks of events I'm interested in. The function that sets the input
masks and calls XSelectInput follows. (The somewhat unusual coding style is
due to this function being part of a locally developed object-oriented
system.  The function is found using method lookup. Instance is a pointer to
the object instance; args and argc reference a stack used to pass in the
variable length arglists, much like XtSetValues.)

------------------------------------------------------------------------------
HIDE XWINDOW *
xwindow_set_input_mask(instance, argc, args)
	XWINDOW *instance;
	int argc;
	ARGUMENT *args;
{

  unsigned long mask;

  if (argc < 1)
    return(instance);

  /* instance is an xwindow object with display and (window) id fields */
  if (instance->display && instance->id)
    {

      Display *display;
      XWindowAttributes win_attr;

      ARGS_BEGIN;	/* open stack frame */
      msg_send_object(instance->display, "id?", 0, 0);
      display = (Display *)ARGS_GET_OBJECT(ARGS_LIST); /* get arg from stack */
      ARGS_END;		/* close stack frame */

      /* first, see what the current event attrs are for the window */
      XGetWindowAttributes(display, instance->id, &win_attr);

      if (instance->debug)
	{
	  /* mask_name() just converts a mask into a readable string */
	  printf("%s: Input mask for this client on window 0x%x:\n  %s\n",
		 instance->name,
		 instance->id,
		 mask_name(win_attr.your_event_mask));

	  printf("%s: Event masks selected by all clients on window 0x%x:\n  %s\n",
		 instance->name,
		 instance->id,
		 mask_name(win_attr.all_event_masks));

	  printf("%s: Do not propagate mask on window 0x%x:\n  %s\n",
		 instance->name, instance->id,
		 mask_name(win_attr.do_not_propagate_mask));
	}

      instance->input_mask = NoEventMask;

      /* now, get masks from the arg stack and build a mask for XSelectInput */
      while (argc)
	{
	  mask = (unsigned long)ARGS_GET_FLOAT(args); args++; argc--;
	  switch (mask)
	    {
	    case ButtonPressMask:
	    case SubstructureRedirectMask:
	    case ResizeRedirectMask:
	      if (win_attr.all_event_masks & mask &&
		  !(win_attr.your_event_mask & mask))
		{
		  /* don't add to input mask - another client is selecting
		     for it already. See XSelectInput() in Xlib Reference
		     Manual */
		  if (instance->debug)
		    printf("%s: Event mask %s selected on window 0x%x by another client.\n",
			   instance->name,
			   mask_name(mask),
			   instance->id);
		}
	      else
		{
		  instance->input_mask |= mask;
		}
	      break;

	    default:
	      instance->input_mask |= mask;
	      break;
	    }
	}

      XSelectInput(display, instance->id, instance->input_mask);

      /* once set, examine the final event attributes for the window */
      if (instance->debug)
	{
	  XGetWindowAttributes(display, instance->id, &win_attr);
	  printf("%s: Input mask for this client on window 0x%x:\n  %s\n",
		 instance->name,
		 instance->id,
		 mask_name(win_attr.your_event_mask));

	  printf("%s: Event masks selected by all clients on window 0x%x:\n  %s\n",
		 instance->name,
		 instance->id,
		 mask_name(win_attr.all_event_masks));

	  printf("%s: Do not propagate mask on window 0x%x:\n  %s\n",
		 instance->name, instance->id,
		 mask_name(win_attr.do_not_propagate_mask));
	}

    }

  return(instance);

}
------------------------------------------------------------------------------

The output from the two calls to the above function follows (I've
line-wrapped it and chunked the output for better readability):

  before XSelectInput
    outer_win: Input mask for this client on window 0x900005:
      NoEventMask
    outer_win: Event masks selected by all clients on window 0x900005:
      EnterWindowMask|LeaveWindowMask
    outer_win: Do not propagate mask on window 0x900005:
      NoEventMask

  after XSelectInput
    outer_win: Input mask for this client on window 0x900005:
      KeyReleaseMask|ButtonPressMask|ButtonReleaseMask|PointerMotionMask|
	PointerMotionHintMask|ButtonMotionMask|OwnerGrabButtonMask
    outer_win: Event masks selected by all clients on window 0x900005:
      KeyReleaseMask|ButtonPressMask|ButtonReleaseMask|EnterWindowMask|
	LeaveWindowMask|PointerMotionMask|PointerMotionHintMask|
	ButtonMotionMask|OwnerGrabButtonMask
    outer_win: Do not propagate mask on window 0x900005:
      NoEventMask

  before XSelectInput
    wkspc_win: Input mask for this client on window 0x900006:
      NoEventMask
    wkspc_win: Event masks selected by all clients on window 0x900006:
      KeyPressMask|ButtonPressMask|ButtonReleaseMask|EnterWindowMask|
	LeaveWindowMask|ExposureMask
    wkspc_win: Do not propagate mask on window 0x900006:
      NoEventMask
    wkspc_win: Event mask ButtonPressMask selected on window 0x900006 by
	another client.

  after XSelectInput
    wkspc_win: Input mask for this client on window 0x900006:
      KeyReleaseMask|ButtonReleaseMask|PointerMotionMask|PointerMotionHintMask|
	ButtonMotionMask|OwnerGrabButtonMask
    wkspc_win: Event masks selected by all clients on window 0x900006:
      KeyPressMask|KeyReleaseMask|ButtonPressMask|ButtonReleaseMask|
	EnterWindowMask|LeaveWindowMask|PointerMotionMask|
	PointerMotionHintMask|ButtonMotionMask|ExposureMask|OwnerGrabButtonMask
    wkspc_win: Do not propagate mask on window 0x900006:
      NoEventMask

For the row/column widget, I called the function with OwnerGrabButtonMask,
ButtonMotionMask, PointerMotionMask, PointerMotionHintMask, KeyReleaseMask,
ButtonPressMask, and ButtonReleaseMask. For the workspace widget, I called
it with OwnerGrabButtonMask, ButtonMotionMask, ButtonPressMask,
PointerMotionMask, PointerMotionHintMask, KeyReleaseMask, and
ButtonReleaseMask.

When all is said and done, the application sees no MotionNotify events. I've
tried running it connected to xmon, and xmon sees and reports MotionNotify
events when no mouse buttons are pressed. It reports them as being directed
to window 0x900006, the workspace widget. I never see MotionNotify events
when any mouse buttons are pressed (not even by xmon).

I also can't understand why the row/column widget can select for ButtonPress
and the workspace widget can't. Aren't they part of the same client?
ButtonPressMask is initially in all_event_masks for the workspace window,
but not in your_event_mask, so I don't add it to the input for XSelectInput.
If I leave it in (by eliminating the logic in the switch statement), I get a
BadAccess error from the server. What other clients would have access to the
workspace window's widget?

Any ideas at all would be helpful.

Thanks,

--
Skip (montanaro@crdgw1.ge.com)

montnaro@spyder.crd.ge.com (Skip Montanaro) (11/29/90)

Here are a few more more things I've tried, with no success.

    1. I tried running the X11R4 server instead of OW2.0. No change.

    2. I switched my application to use the motif widgets. The only change I
       noticed was that the application received two MapNotify events during
       initialization instead of one.

    3. I removed the row/column widget. The only widget then was either an
       HP workspace widget or a Motif drawing area widget.

    4. I tried both mwm and olwm as the window manager.

Still stumped,

--
Skip (montanaro@crdgw1.ge.com)