--- 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;
-}