1 /* 2 * Licensed to the Apache Software Foundation (ASF) under one or more 3 * contributor license agreements. See the NOTICE file distributed with 4 * this work for additional information regarding copyright ownership. 5 * The ASF licenses this file to You under the Apache License, Version 2.0 6 * (the "License"); you may not use this file except in compliance with 7 * the License. You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 */ 17 /** 18 * @author Pavel Dolgov 19 * @version $Revision$ 20 */ 21 package java.awt; 22 23 import java.awt.event.ActionEvent; 24 import java.awt.event.InputEvent; 25 import java.awt.event.InputMethodEvent; 26 import java.awt.event.InvocationEvent; 27 import java.awt.event.MouseEvent; 28 import java.util.LinkedList; 29 30 import org.apache.harmony.awt.internal.nls.Messages; 31 32 /** 33 * The events storage for EventQueue 34 */ 35 final class EventQueueCore { 36 37 private final LinkedList<EventQueue> queueStack = new LinkedList<EventQueue>(); 38 private final LinkedList<AWTEvent> events = new LinkedList<AWTEvent>(); 39 40 private Toolkit toolkit; 41 private EventQueue activeQueue; 42 private Thread dispatchThread; 43 44 AWTEvent currentEvent; 45 long mostRecentEventTime = System.currentTimeMillis(); 46 47 EventQueueCore(EventQueue eq) { 48 synchronized (this) { 49 queueStack.addLast(eq); 50 activeQueue = eq; 51 } 52 } 53 54 EventQueueCore(EventQueue eq, Toolkit t) { 55 synchronized (this) { 56 queueStack.addLast(eq); 57 activeQueue = eq; 58 setToolkit(t); 59 } 60 } 61 62 synchronized long getMostRecentEventTime() { 63 return mostRecentEventTime; 64 } 65 66 synchronized AWTEvent getCurrentEvent() { 67 return currentEvent; 68 } 69 70 synchronized boolean isSystemEventQueue() { 71 return toolkit != null; 72 } 73 74 private void setToolkit(Toolkit t) { 75 toolkit = t; 76 if (toolkit != null) { 77 toolkit.setSystemEventQueueCore(this); 78 dispatchThread = toolkit.dispatchThread; 79 } 80 } 81 82 synchronized void postEvent(AWTEvent event) { 83 //???AWT 84 /* 85 events.addLast(event); 86 if ((toolkit == null) && (dispatchThread == null)) { 87 dispatchThread = new EventQueueThread(this); 88 dispatchThread.start(); 89 } 90 // TODO: add event coalescing 91 if (toolkit != null) { 92 toolkit.shutdownWatchdog.setAwtQueueEmpty(false); 93 if (!GraphicsEnvironment.getLocalGraphicsEnvironment().isHeadlessInstance()) { 94 notifyEventMonitor(toolkit); 95 } 96 } 97 notifyAll(); 98 */ 99 } 100 101 void notifyEventMonitor(Toolkit t) { 102 Object em = t.getNativeEventQueue().getEventMonitor(); 103 synchronized (em) { 104 em.notifyAll(); 105 } 106 } 107 108 synchronized AWTEvent getNextEvent() throws InterruptedException { 109 while (events.isEmpty()) { 110 wait(); 111 } 112 AWTEvent event = events.removeFirst(); 113 // TODO: add event coalescing 114 return event; 115 } 116 117 synchronized AWTEvent peekEvent() { 118 return events.isEmpty() ? null : events.getFirst(); 119 } 120 121 synchronized AWTEvent peekEvent(int id) { 122 for (AWTEvent event : events) { 123 if (event.getID() == id) { 124 return event; 125 } 126 } 127 return null; 128 } 129 130 synchronized void dispatchEvent(AWTEvent event) { 131 updateCurrentEventAndTime(event); 132 try { 133 activeQueue.dispatchEvent(event); 134 } finally { 135 currentEvent = null; 136 } 137 } 138 139 void dispatchEventImpl(AWTEvent event) { 140 if (event instanceof ActiveEvent) { 141 updateCurrentEventAndTime(event); 142 try { 143 ((ActiveEvent) event).dispatch(); 144 } finally { 145 currentEvent = null; 146 } 147 return; 148 } 149 150 Object src = event.getSource(); 151 152 if (src instanceof Component) { 153 if (preprocessComponentEvent(event)) { 154 ((Component) src).dispatchEvent(event); 155 } 156 } else { 157 if (toolkit != null) { 158 toolkit.dispatchAWTEvent(event); 159 } 160 if (src instanceof MenuComponent) { 161 ((MenuComponent) src).dispatchEvent(event); 162 } 163 } 164 } 165 166 private final boolean preprocessComponentEvent(AWTEvent event) { 167 if (event instanceof MouseEvent) { 168 return preprocessMouseEvent((MouseEvent)event); 169 } 170 return true; 171 } 172 173 private final boolean preprocessMouseEvent(MouseEvent event) { 174 //???AWT 175 /* 176 if (toolkit != null && toolkit.mouseEventPreprocessor != null) { 177 toolkit.lockAWT(); 178 try { 179 return toolkit.mouseEventPreprocessor.preprocess(event); 180 } finally { 181 toolkit.unlockAWT(); 182 } 183 } 184 return true; 185 */ 186 return true; 187 } 188 189 private void updateCurrentEventAndTime(AWTEvent event) { 190 currentEvent = event; 191 long when = 0; 192 if (event instanceof ActionEvent) { 193 when = ((ActionEvent) event).getWhen(); 194 } else if (event instanceof InputEvent) { 195 when = ((InputEvent) event).getWhen(); 196 } else if (event instanceof InputMethodEvent) { 197 when = ((InputMethodEvent) event).getWhen(); 198 } else if (event instanceof InvocationEvent) { 199 when = ((InvocationEvent) event).getWhen(); 200 } 201 if (when != 0) { 202 mostRecentEventTime = when; 203 } 204 } 205 206 synchronized void push(EventQueue newEventQueue) { 207 // TODO: handle incorrect situations 208 if (queueStack.isEmpty()) { 209 // awt.6B=Queue stack is empty 210 throw new IllegalStateException(Messages.getString("awt.6B")); //$NON-NLS-1$ 211 } 212 213 queueStack.addLast(newEventQueue); 214 activeQueue = newEventQueue; 215 activeQueue.setCore(this); 216 } 217 218 synchronized void pop() { 219 EventQueue removed = queueStack.removeLast(); 220 if (removed != activeQueue) { 221 // awt.6C=Event queue stack is broken 222 throw new IllegalStateException(Messages.getString("awt.6C")); //$NON-NLS-1$ 223 } 224 activeQueue = queueStack.getLast(); 225 removed.setCore(null); 226 } 227 228 synchronized AWTEvent getNextEventNoWait() { 229 try { 230 return events.isEmpty() ? null : activeQueue.getNextEvent(); 231 } catch (InterruptedException e) { 232 return null; 233 } 234 } 235 236 synchronized boolean isEmpty() { 237 return (currentEvent == null) && events.isEmpty(); 238 } 239 240 synchronized boolean isEmpty(long timeout) { 241 if (!isEmpty()) { 242 return false; 243 } 244 try { 245 wait(timeout); 246 } catch (InterruptedException e) {} 247 return isEmpty(); 248 } 249 250 synchronized EventQueue getActiveEventQueue() { 251 return activeQueue; 252 } 253 } 254