From: greg@thirdi.uucp (Greg Holmberg)
Newsgroups: comp.windows.x.motif,comp.windows.open-look
Subject: Re: XtAppCreateShell
Keywords: Motif,shell,OpenLook,HP
Date: 8 Oct 92 22:02:05 GMT
Reply-To: greg@thirdi.UUCP (Greg Holmberg)
Organization: Third Eye Software, Menlo Park, CA

In article <wH39RB2w165w@tmchome.UUCP> tchal@tmchome.UUCP (Thomas M. Chalfant) writes:
	I have trouble with a particular Motif item not working under
	OpenWindows 3.0.  Popup menus activated with the third mouse
	button work fine under the MIT X server, but hang the OW3 X
	server.  A trace on the server reveals a tight loop.  Our sun
	rep took the problem report but their response has been...  It
	must be a programmer error.  However; Island Write, Island
	Paint, and Island Draw all use popups, and all work fine under
	the MIT X server, but exhibit the same response as my programs
	when running under the OW3 X server.  Any ideas on this?

I've seen a similar problem under OpenWindow 3.0 and Motif with the
middle mouse button (quickPaste in Motif): a never released grab locks
up the server.  I'm including a copy of the bug report I sent to
sunbugs@sun.com.  I'm also including the work-around I have for it.

Regarding Btn3, I will say that our Motif 1.1.4 based application has no
problem popping up menus from Btn3 under OW 2 or 3.  I set:

    *searches.translations: #augment <Btn3Down>: MriPopupACT(*srchPUM)

MriPopupACT does an XmMenuPosition and an XtManageChild.


Greg Holmberg

Third Eye Software, Inc.                415/321-0967 Voice
750 Menlo Avenue, Suite 300             415/321-2066 Fax
Menlo Park, CA  94025                   greg@thirdeye.com



Here's my work-around for the Btn2 problem (bug report follows):


int (*prevError) PARMS((Display *, XErrorEvent *));


Boolean UngrabWP(closure)
XtPointer closure;

    /*
     * A Motif Text widget may have grabbed the keyboard or pointer
     * if the user quick-pasted (Btn2 drag) in it.
     * If XSetSelectionOwner fails, those are never ungrabbed
     * and server is locked up.  We return the pointer and keyboard
     * to the user here.  Stupid OpenWindows!
     */

{
    XUngrabKeyboard((Display *) closure, CurrentTime);
    XUngrabPointer((Display *) closure, CurrentTime);
    return True;  /* means remove this workproc */
}


int XError(display, err)
Display *display;
XErrorEvent *err;

    /*
     * This is for a bug in the OpenWindows 3 xnews server:
     * it doesn't implement the SetSelectionOwner operation!
     * (at least sometimes.)
     */

{

    if (err->error_code == BadImplementation) {
	static FLAGT fNotified = false;
	if (!fNotified) {
	    char sbOperation[40];

	    XGetErrorDatabaseText(display, "XRequest", 
		SbFFormat(sbNil, "%d", err->request_code),
		"Unknown operation code",
		sbOperation, sizeof(sbOperation));

	    fprintf(stderr, "\
Your server, %s, is defective.\n\
It doesn't implement the %s operation,\n\
a basic part of the X protocol.\n",
		display->vendor, sbOperation);
	    fNotified = true;
	}
	if (err->request_code == X_SetSelectionOwner) {
	    /*
	     * Have to do this in a workproc because you're not supposed
	     * to request any operations from the server while in the
	     * error handler.
	     */
	    XtAppAddWorkProc(XApp, UngrabWP, (XtPointer) display);
	}
	return 0;
    }

    return (*prevError)(display, err);
}

During startup:

    prevError = XSetErrorHandler(XError);


============================= BUG REPORT TO SUN ===========================

I would like to report a bug in the X11/NeWS server that comes with
OpenWindows 3.  xdpyinfo says:

	version number:    11.0
	vendor string:    X11/NeWS - Sun Microsystems Inc.
	vendor release number:    3000

I'm running SunOS 4.1.1.  The bug does not occur in OpenWindows 2.

The server apparently doesn't implement a basic part of the X protocol,
the X_SetSelectionOwner operation (usually used for Cut&Paste).

I consider this a very severe bug because it can result in the pointer and
keyboard being permanently grabbed, resulting in a unusable machine until
the client is killed from another terminal.

A short program that recreates the bug is included at the end.

Here's what happens: if you call XSetSelectionOwner(), an error event
comes back from the server.  The error_code is BadImplementation and
the request_code is X_SetSelectionOwner.

This is especially a problem with Motif applications (I'm using 1.1.4).
If a user quick-pastes (Btn2 drag) in a Motif XmText widget, the widget
calls XGrabKeyboard, XSetSelectionOwner three times and finally
XUngrabKeyboard.  I believe this is all done in the X Toolkit function
XtOwnSelection (I'm using X11R5).

With the OpenWindows 3 xnews server, the first XSetSelectionOwner fails,
the other two XSetSelectionOwner calls and the XUngrabKeyboard call are never
made.  This leaves the X server in a grabbed state.  Now you have to kill
the client to get your keyboard and mouse back.

I would imagine that this would happen to any client using the R5
XtOwnSelection() function, and is NOT specific to Motif.

When this happens, olwm simultaneously prints that it failed to grab
the pointer.

I have noticed that sometimes, after running for a while, the xnews
server no longer sends this error event.  It's as if something got
installed or initialized at a later point, and the server could then
handle the SetSelectionOwner request.  So to reproduce it, run it
against a freshly started server.  Perhaps the bug is merely that
something didn't get initialized on startup?

Please contact me if you need any further information.  Also, if you have
a work-around or an upgrade to OpenWindows for this problem, I would like
to know.

For now, I have installed my own error handler with XSetErrorHandler() and
am looking for BadImplementation and X_SetSelectionOwner and then
ungrabbing the keyboard and pointer.  This work-around seems to get the
display freed up, but of course, the user still can't do a quick paste.


============================ RECREATES BUG =================================

#include <stdio.h>
#include <X11/Xlib.h>
#include <X11/Xatom.h>

#define isNil(p) (((void *) (p)) == ((void *) 0))

extern void perror(char *);

int main(int argc, char *argv[])

{
    Display *display;

    display = XOpenDisplay(argv[1]);
    if (isNil(display)) {
	perror("open display");
	return 1;
    }

    XSetSelectionOwner(display, XA_SECONDARY, DefaultRootWindow(display),
	CurrentTime);

    /*
     The above call results in the following error under Sun OpenWindows 3:

X Error of failed request:  BadImplementation (server does not implement operation)
  Major opcode of failed request:  22 (X_SetSelectionOwner)
  Serial number of failed request:  3
  Current serial number in output stream:  5

    */

    XCloseDisplay(display);
    return 0;
}