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)