1/*
2 * Copyright (c) 2003, 2014, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.  Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25
26package sun.awt.X11;
27
28import java.util.Iterator;
29
30/**
31 * This class is a registry for the supported drag and drop protocols.
32 *
33 * @since 1.5
34 */
35final class XDropTargetEventProcessor {
36    private static final XDropTargetEventProcessor theInstance =
37        new XDropTargetEventProcessor();
38    private static boolean active = false;
39
40    // The current drop protocol.
41    private XDropTargetProtocol protocol = null;
42
43    private XDropTargetEventProcessor() {}
44
45    private boolean doProcessEvent(XEvent ev) {
46        if (ev.get_type() == XConstants.DestroyNotify &&
47            protocol != null &&
48            ev.get_xany().get_window() == protocol.getSourceWindow()) {
49            protocol.cleanup();
50            protocol = null;
51            return false;
52        }
53
54        if (ev.get_type() == XConstants.PropertyNotify) {
55            XPropertyEvent xproperty = ev.get_xproperty();
56            if (xproperty.get_atom() ==
57                MotifDnDConstants.XA_MOTIF_DRAG_RECEIVER_INFO.getAtom()) {
58
59                XDropTargetRegistry.getRegistry().updateEmbedderDropSite(xproperty.get_window());
60            }
61        }
62
63        if (ev.get_type() != XConstants.ClientMessage) {
64            return false;
65        }
66
67        boolean processed = false;
68        XClientMessageEvent xclient = ev.get_xclient();
69
70        XDropTargetProtocol curProtocol = protocol;
71
72        if (protocol != null) {
73            if (protocol.getMessageType(xclient) !=
74                XDropTargetProtocol.UNKNOWN_MESSAGE) {
75                processed = protocol.processClientMessage(xclient);
76            } else {
77                protocol = null;
78            }
79        }
80
81        if (protocol == null) {
82            Iterator<XDropTargetProtocol> dropTargetProtocols =
83                XDragAndDropProtocols.getDropTargetProtocols();
84
85            while (dropTargetProtocols.hasNext()) {
86                XDropTargetProtocol dropTargetProtocol = dropTargetProtocols.next();
87                // Don't try to process it again with the current protocol.
88                if (dropTargetProtocol == curProtocol) {
89                    continue;
90                }
91
92                if (dropTargetProtocol.getMessageType(xclient) ==
93                    XDropTargetProtocol.UNKNOWN_MESSAGE) {
94                    continue;
95                }
96
97                protocol = dropTargetProtocol;
98                processed = protocol.processClientMessage(xclient);
99                break;
100            }
101        }
102
103        return processed;
104    }
105
106    static void reset() {
107        theInstance.protocol = null;
108    }
109
110    static void activate() {
111        active = true;
112    }
113
114    // Fix for 4915454 - do not call doProcessEvent() until the first drop
115    // target is registered to avoid premature loading of DnD protocol
116    // classes.
117    static boolean processEvent(XEvent ev) {
118        return active ? theInstance.doProcessEvent(ev) : false;
119    }
120}
121