jdk/src/solaris/native/sun/awt/awt_mgrsel.c
changeset 11319 a3d37054381f
parent 11318 e114b7d53b9b
parent 11239 885050364691
child 11320 1ed269f7cc73
--- a/jdk/src/solaris/native/sun/awt/awt_mgrsel.c	Wed Dec 14 21:52:59 2011 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,449 +0,0 @@
-/*
- * Copyright (c) 2003, 2004, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-#ifdef HEADLESS
-    #error This file should not be included in headless library
-#endif
-
-#include "awt_mgrsel.h"
-
-static Atom XA_MANAGER = None;
-
-/*
- * Structures that describes the manager selection AWT listens to with
- * callabacks to the subsytems interested in the selection.  (We only
- * listen to a couple of selections, so linear search is enough).
- */
-struct AwtMgrsel {
-    char *selname;              /* base name of selection atoms */
-    Atom *per_scr_atoms;        /* per-screen selection atoms (ICCCM 1.2.6) */
-    Atom *per_scr_owners;       /* windows currently owning the selection */
-    long extra_mask;            /* extra events to listen to on owners */
-    void *cookie;
-    void (*callback_event)(int, XEvent *, void *); /* extra_mask events */
-    void (*callback_owner)(int, Window, long *, void *); /* owner changes */
-    struct AwtMgrsel *next;
-};
-
-static struct AwtMgrsel *mgrsel_list = NULL;
-
-
-static int awt_mgrsel_screen(Window w);
-static Window awt_mgrsel_select_per_screen(Atom, long);
-static int awt_mgrsel_managed(XClientMessageEvent *mgrown);
-static int awt_mgrsel_unmanaged(XDestroyWindowEvent *ev);
-
-#ifdef DEBUG
-static void awt_mgrsel_dtraceManaged(XClientMessageEvent *mgrown);
-#endif
-
-
-
-/*
- * Find which screen the window W is the root of.
- * Returns the screen number, or -1 if W is not a root.
- */
-static int
-awt_mgrsel_screen(Window w)
-{
-    Display *dpy = awt_display;
-    int scr;
-
-    for (scr = 0; scr < ScreenCount(dpy); ++scr) {
-        if (w == RootWindow(dpy, scr)) {
-            return (scr);
-        }
-    }
-
-    return (-1);
-}
-
-
-/************************************************************************
- * For every one that asketh receiveth; and he that seeketh findeth;
- * and to him that knocketh it shall be opened.  (Luke 11:10).
- */
-
-
-/*
- * A method for a subsytem to express its interest in a certain
- * manager selection.
- *
- * If owner changes, the callback_owner will be called with the screen
- * number and the new owning window when onwership is established, or
- * None if the owner is gone.
- *
- * Events in extra_mask are selected for on owning windows (exsiting
- * ones and on new owners when established) and callback_event will be
- * called with the screen number and an event.
- *
- * The function returns an array of current owners.  The size of the
- * array is ScreenCount(awt_display).  The array is "owned" by this
- * module and should be considered by the caller as read-only.
- */
-const Window *
-awt_mgrsel_select(const char *selname, long extra_mask,
-                  void *cookie,
-                  void (*callback_event)(int, XEvent *, void *),
-                  void (*callback_owner)(int, Window, long *, void *))
-{
-    Display *dpy = awt_display;
-    struct AwtMgrsel *mgrsel;
-    Atom *per_scr_atoms;
-    Window *per_scr_owners;
-    char *namesbuf;
-    char **names;
-    int per_scr_sz;
-    int nscreens = ScreenCount(dpy);
-    int scr;
-    Status status;
-
-    DASSERT(selname != NULL);
-    DTRACE_PRINTLN1("MG: select: %s", selname);
-
-    /* buffer size for one per-screen atom name */
-    per_scr_sz = strlen(selname) + /* "_S" */ 2 + /* %2d */ + 2 /* '\0' */+ 1;
-
-    namesbuf = malloc(per_scr_sz * nscreens);  /* actual storage for names */
-    names = malloc(sizeof(char *) * nscreens); /* pointers to names */
-    per_scr_atoms = malloc(sizeof(Atom) * nscreens);
-    per_scr_owners = malloc(sizeof(Window) * nscreens);
-    mgrsel = malloc(sizeof(struct AwtMgrsel));
-
-    if (namesbuf == NULL || names == NULL || per_scr_atoms == NULL
-        || per_scr_owners == NULL || mgrsel == NULL)
-    {
-        DTRACE_PRINTLN("MG: select: unable to allocate memory");
-        if (namesbuf != NULL) free(namesbuf);
-        if (names != NULL) free(names);
-        if (per_scr_atoms != NULL) free(per_scr_atoms);
-        if (per_scr_owners != NULL) free(per_scr_owners);
-        if (mgrsel != NULL) free(mgrsel);
-        return (NULL);
-    }
-
-
-    for (scr = 0; scr < nscreens; ++scr) {
-        size_t sz;
-
-        names[scr] = &namesbuf[per_scr_sz * scr];
-        sz = snprintf(names[scr], per_scr_sz, "%s_S%-d", selname, scr);
-        DASSERT(sz < per_scr_sz);
-    }
-
-    status = XInternAtoms(dpy, names, nscreens, False, per_scr_atoms);
-
-    free(names);
-    free(namesbuf);
-
-    if (status == 0) {
-        DTRACE_PRINTLN("MG: select: XInternAtoms failed");
-        free(per_scr_atoms);
-        free(per_scr_owners);
-        return (NULL);
-    }
-
-    mgrsel->selname = strdup(selname);
-    mgrsel->per_scr_atoms = per_scr_atoms;
-    mgrsel->per_scr_owners = per_scr_owners;
-    mgrsel->extra_mask = extra_mask;
-    mgrsel->cookie = cookie;
-    mgrsel->callback_event = callback_event;
-    mgrsel->callback_owner = callback_owner;
-
-    for (scr = 0; scr < nscreens; ++scr) {
-        Window owner;
-
-        owner = awt_mgrsel_select_per_screen(per_scr_atoms[scr], extra_mask);
-        mgrsel->per_scr_owners[scr] = owner;
-#ifdef DEBUG
-        if (owner == None) {
-            DTRACE_PRINTLN1("MG:   screen %d - None", scr);
-        } else {
-            DTRACE_PRINTLN2("MG:   screen %d - 0x%08lx", scr, owner);
-        }
-#endif
-    }
-
-    mgrsel->next = mgrsel_list;
-    mgrsel_list = mgrsel;
-
-    return (per_scr_owners);
-}
-
-
-static Window
-awt_mgrsel_select_per_screen(Atom selection, long extra_mask)
-{
-    Display *dpy = awt_display;
-    Window owner;
-
-    XGrabServer(dpy);
-
-    owner = XGetSelectionOwner(dpy, selection);
-    if (owner == None) {
-        /* we'll get notified later if one arrives */
-        XUngrabServer(dpy);
-        /* Workaround for bug 5039226 */
-        XSync(dpy, False);
-        return (None);
-    }
-
-    /*
-     * Select for StructureNotifyMask to get DestroyNotify when owner
-     * is gone.  Also select for any additional events caller is
-     * interested in (e.g. PropertyChangeMask).  Caller will be
-     * notifed of these events via ... XXX ...
-     */
-    XSelectInput(dpy, owner, StructureNotifyMask | extra_mask);
-
-    XUngrabServer(dpy);
-    /* Workaround for bug 5039226 */
-    XSync(dpy, False);
-    return (owner);
-}
-
-
-/************************************************************************
- * And so I saw the wicked buried, who had come and gone from the
- * place of the holy, and they were forgotten in the city where they
- * had so done: this is also vanity.  (Eccl 8:10)
- */
-
-#ifdef DEBUG
-/*
- * Print the message from the new manager that announces it acquired
- * ownership.
- */
-static void
-awt_mgrsel_dtraceManaged(XClientMessageEvent *mgrown)
-{
-    Display *dpy = awt_display;
-    Atom selection;
-    char *selname, *print_selname;
-    int scr;
-
-    scr = awt_mgrsel_screen(mgrown->window);
-
-    selection = mgrown->data.l[1];
-    print_selname = selname = XGetAtomName(dpy, selection);
-    if (selname == NULL) {
-        if (selection == None) {
-            print_selname = "<None>";
-        } else {
-            print_selname = "<Unknown>";
-        }
-    }
-
-    DTRACE_PRINTLN4("MG: new MANAGER for %s: screen %d, owner 0x%08lx (@%lu)",
-                   print_selname, scr,
-                   mgrown->data.l[2],  /* the window owning the selection */
-                   mgrown->data.l[0]); /* timestamp */
-    DTRACE_PRINTLN4("MG:   %ld %ld / 0x%lx 0x%lx", /* extra data */
-                    mgrown->data.l[3], mgrown->data.l[4],
-                    mgrown->data.l[3], mgrown->data.l[4]);
-
-    if (selname != NULL) {
-        XFree(selname);
-    }
-}
-#endif /* DEBUG */
-
-
-static int
-awt_mgrsel_managed(XClientMessageEvent *mgrown)
-{
-    Display *dpy = awt_display;
-    struct AwtMgrsel *mgrsel;
-    int scr;
-
-    long timestamp;
-    Atom selection;
-    Window owner;
-    long *data;
-
-    if (mgrown->message_type != XA_MANAGER) {
-        DTRACE_PRINTLN("MG: ClientMessage type != MANAGER, ignoring");
-        return (0);
-    }
-
-    scr = awt_mgrsel_screen(mgrown->window);
-
-#ifdef DEBUG
-    awt_mgrsel_dtraceManaged(mgrown);
-#endif
-
-    if (scr < 0) {
-        DTRACE_PRINTLN("MG: MANAGER ClientMessage with a non-root window!");
-        return (0);
-    }
-
-    timestamp = mgrown->data.l[0];
-    selection = mgrown->data.l[1];
-    owner     = mgrown->data.l[2];
-    data      = &mgrown->data.l[3]; /* long[2], selection specific */
-
-    /* is this a selection we are intrested in? */
-    for (mgrsel = mgrsel_list; mgrsel != NULL; mgrsel = mgrsel->next) {
-        if (selection == mgrsel->per_scr_atoms[scr])
-            break;
-    }
-
-    if (mgrsel == NULL) {
-        DTRACE_PRINTLN("MG: not interested in this selection, ignoring");
-        return (0);
-    }
-
-
-    mgrsel->per_scr_owners[scr] = owner;
-
-    XSelectInput(dpy, owner, StructureNotifyMask | mgrsel->extra_mask);
-
-    /* notify the listener */
-    if (mgrsel->callback_owner != NULL) {
-        (*mgrsel->callback_owner)(scr, owner, data, mgrsel->cookie);
-    }
-
-    return (1);
-}
-
-
-static int
-awt_mgrsel_unmanaged(XDestroyWindowEvent *ev)
-{
-    Display *dpy = awt_display;
-    struct AwtMgrsel *mgrsel;
-    Window exowner;
-    int scr;
-
-    exowner = ev->window;       /* selection owner that's gone */
-
-    /* is this a selection we are intrested in? */
-    for (mgrsel = mgrsel_list; mgrsel != NULL; mgrsel = mgrsel->next) {
-        for (scr = 0; scr < ScreenCount(dpy); ++scr) {
-            if (exowner == mgrsel->per_scr_owners[scr]) {
-                /* can one window own selections for more than one screen? */
-                goto out;       /* XXX??? */
-            }
-        }
-    }
-  out:
-    if (mgrsel == NULL) {
-        DTRACE_PRINTLN1("MG: DestroyNotify for 0x%08lx ignored", exowner);
-        return (0);
-    }
-
-    DTRACE_PRINTLN3("MG: DestroyNotify for 0x%08lx, owner of %s at screen %d",
-                    exowner, mgrsel->selname, scr);
-
-    /* notify the listener (pass exowner as data???) */
-    if (mgrsel->callback_owner != NULL) {
-        (*mgrsel->callback_owner)(scr, None, NULL, mgrsel->cookie);
-    }
-
-    return (1);
-}
-
-
-/*
- * Hook to be called from toolkit event loop.
- */
-int
-awt_mgrsel_processEvent(XEvent *ev)
-{
-    Display *dpy = awt_display;
-    struct AwtMgrsel *mgrsel;
-    int scr;
-
-    if (ev->type == ClientMessage) { /* new manager announces ownership? */
-        if (awt_mgrsel_managed(&ev->xclient))
-            return (1);
-    }
-
-    if (ev->type == DestroyNotify) { /* manager gives up selection? */
-        if (awt_mgrsel_unmanaged(&ev->xdestroywindow))
-            return (1);
-    }
-
-    /* is this an event selected on one of selection owners? */
-    for (mgrsel = mgrsel_list; mgrsel != NULL; mgrsel = mgrsel->next) {
-        for (scr = 0; scr < ScreenCount(dpy); ++scr) {
-            if (ev->xany.window == mgrsel->per_scr_owners[scr]) {
-                /* can one window own selections for more than one screen? */
-                goto out;       /* XXX??? */
-            }
-        }
-    }
-  out:
-    DTRACE_PRINT2("MG: screen %d, event %d ...  ",
-                  scr, ev->xany.type);
-    if (mgrsel == NULL) {
-        DTRACE_PRINTLN("ignored");
-        return (0);             /* not interested */
-    }
-
-    DTRACE_PRINT1("%s ...  ", mgrsel->selname);
-    if (mgrsel->callback_event != NULL) {
-        DTRACE_PRINTLN("dispatching");
-        (*mgrsel->callback_event)(scr, ev, mgrsel->cookie);
-    }
-#ifdef DEBUG
-    else {
-        DTRACE_PRINTLN("no callback");
-    }
-#endif
-
-    return (1);
-}
-
-
-void
-awt_mgrsel_init(void)
-{
-    static Boolean inited = False;
-
-    Display *dpy = awt_display;
-    int scr;
-
-    if (inited) {
-        return;
-    }
-
-    XA_MANAGER = XInternAtom(dpy, "MANAGER", False);
-    DASSERT(XA_MANAGER != None);
-
-
-    /*
-     * Listen for ClientMessage's on each screen's root.  We hook into
-     * the message loop in the toolkit (with awt_mgrsel_processEvent)
-     * to get the events processed.  We need this for notifications of
-     * new manager acquiring ownership of the manager selection.
-     */
-    for (scr = 0; scr < ScreenCount(dpy); ++scr) {
-        XSelectInput(dpy, RootWindow(dpy, scr), StructureNotifyMask);
-    }
-
-    inited = True;
-}