1 /*
   2  * Copyright (c) 1996, 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 
  26 package java.awt;
  27 
  28 import java.util.EventObject;
  29 import java.awt.event.*;
  30 import java.awt.peer.ComponentPeer;
  31 import java.awt.peer.LightweightPeer;
  32 import java.lang.reflect.Field;
  33 import sun.awt.AWTAccessor;
  34 import sun.util.logging.PlatformLogger;
  35 
  36 import java.security.AccessControlContext;
  37 import java.security.AccessController;
  38 
  39 /**
  40  * The root event class for all AWT events.
  41  * This class and its subclasses supersede the original
  42  * java.awt.Event class.
  43  * Subclasses of this root AWTEvent class defined outside of the
  44  * java.awt.event package should define event ID values greater than
  45  * the value defined by RESERVED_ID_MAX.
  46  * <p>
  47  * The event masks defined in this class are needed by Component subclasses
  48  * which are using Component.enableEvents() to select for event types not
  49  * selected by registered listeners. If a listener is registered on a
  50  * component, the appropriate event mask is already set internally by the
  51  * component.
  52  * <p>
  53  * The masks are also used to specify to which types of events an
  54  * AWTEventListener should listen. The masks are bitwise-ORed together
  55  * and passed to Toolkit.addAWTEventListener.
  56  *
  57  * @see Component#enableEvents
  58  * @see Toolkit#addAWTEventListener
  59  *
  60  * @see java.awt.event.ActionEvent
  61  * @see java.awt.event.AdjustmentEvent
  62  * @see java.awt.event.ComponentEvent
  63  * @see java.awt.event.ContainerEvent
  64  * @see java.awt.event.FocusEvent
  65  * @see java.awt.event.InputMethodEvent
  66  * @see java.awt.event.InvocationEvent
  67  * @see java.awt.event.ItemEvent
  68  * @see java.awt.event.HierarchyEvent
  69  * @see java.awt.event.KeyEvent
  70  * @see java.awt.event.MouseEvent
  71  * @see java.awt.event.MouseWheelEvent
  72  * @see java.awt.event.PaintEvent
  73  * @see java.awt.event.TextEvent
  74  * @see java.awt.event.WindowEvent
  75  *
  76  * @author Carl Quinn
  77  * @author Amy Fowler
  78  * @since 1.1
  79  */
  80 public abstract class AWTEvent extends EventObject {
  81     private static final PlatformLogger log = PlatformLogger.getLogger("java.awt.AWTEvent");
  82     private byte bdata[];
  83 
  84     /**
  85      * The event's id.
  86      * @serial
  87      * @see #getID()
  88      * @see #AWTEvent
  89      */
  90     protected int id;
  91 
  92     /**
  93      * Controls whether or not the event is sent back down to the peer once the
  94      * source has processed it - false means it's sent to the peer; true means
  95      * it's not. Semantic events always have a 'true' value since they were
  96      * generated by the peer in response to a low-level event.
  97      * @serial
  98      * @see #consume
  99      * @see #isConsumed
 100      */
 101     protected boolean consumed = false;
 102 
 103    /*
 104     * The event's AccessControlContext.
 105     */
 106     private transient volatile AccessControlContext acc =
 107         AccessController.getContext();
 108 
 109    /*
 110     * Returns the acc this event was constructed with.
 111     */
 112     final AccessControlContext getAccessControlContext() {
 113         if (acc == null) {
 114             throw new SecurityException("AWTEvent is missing AccessControlContext");
 115         }
 116         return acc;
 117     }
 118 
 119     transient boolean focusManagerIsDispatching = false;
 120     transient boolean isPosted;
 121 
 122     /**
 123      * Indicates whether this AWTEvent was generated by the system as
 124      * opposed to by user code.
 125      */
 126     private transient boolean isSystemGenerated;
 127 
 128     /**
 129      * The event mask for selecting component events.
 130      */
 131     public static final long COMPONENT_EVENT_MASK = 0x01;
 132 
 133     /**
 134      * The event mask for selecting container events.
 135      */
 136     public static final long CONTAINER_EVENT_MASK = 0x02;
 137 
 138     /**
 139      * The event mask for selecting focus events.
 140      */
 141     public static final long FOCUS_EVENT_MASK = 0x04;
 142 
 143     /**
 144      * The event mask for selecting key events.
 145      */
 146     public static final long KEY_EVENT_MASK = 0x08;
 147 
 148     /**
 149      * The event mask for selecting mouse events.
 150      */
 151     public static final long MOUSE_EVENT_MASK = 0x10;
 152 
 153     /**
 154      * The event mask for selecting mouse motion events.
 155      */
 156     public static final long MOUSE_MOTION_EVENT_MASK = 0x20;
 157 
 158     /**
 159      * The event mask for selecting window events.
 160      */
 161     public static final long WINDOW_EVENT_MASK = 0x40;
 162 
 163     /**
 164      * The event mask for selecting action events.
 165      */
 166     public static final long ACTION_EVENT_MASK = 0x80;
 167 
 168     /**
 169      * The event mask for selecting adjustment events.
 170      */
 171     public static final long ADJUSTMENT_EVENT_MASK = 0x100;
 172 
 173     /**
 174      * The event mask for selecting item events.
 175      */
 176     public static final long ITEM_EVENT_MASK = 0x200;
 177 
 178     /**
 179      * The event mask for selecting text events.
 180      */
 181     public static final long TEXT_EVENT_MASK = 0x400;
 182 
 183     /**
 184      * The event mask for selecting input method events.
 185      */
 186     public static final long INPUT_METHOD_EVENT_MASK = 0x800;
 187 
 188     /**
 189      * The pseudo event mask for enabling input methods.
 190      * We're using one bit in the eventMask so we don't need
 191      * a separate field inputMethodsEnabled.
 192      */
 193     static final long INPUT_METHODS_ENABLED_MASK = 0x1000;
 194 
 195     /**
 196      * The event mask for selecting paint events.
 197      */
 198     public static final long PAINT_EVENT_MASK = 0x2000;
 199 
 200     /**
 201      * The event mask for selecting invocation events.
 202      */
 203     public static final long INVOCATION_EVENT_MASK = 0x4000;
 204 
 205     /**
 206      * The event mask for selecting hierarchy events.
 207      */
 208     public static final long HIERARCHY_EVENT_MASK = 0x8000;
 209 
 210     /**
 211      * The event mask for selecting hierarchy bounds events.
 212      */
 213     public static final long HIERARCHY_BOUNDS_EVENT_MASK = 0x10000;
 214 
 215     /**
 216      * The event mask for selecting mouse wheel events.
 217      * @since 1.4
 218      */
 219     public static final long MOUSE_WHEEL_EVENT_MASK = 0x20000;
 220 
 221     /**
 222      * The event mask for selecting window state events.
 223      * @since 1.4
 224      */
 225     public static final long WINDOW_STATE_EVENT_MASK = 0x40000;
 226 
 227     /**
 228      * The event mask for selecting window focus events.
 229      * @since 1.4
 230      */
 231     public static final long WINDOW_FOCUS_EVENT_MASK = 0x80000;
 232 
 233     /**
 234      * WARNING: there are more mask defined privately.  See
 235      * SunToolkit.GRAB_EVENT_MASK.
 236      */
 237 
 238     /**
 239      * The maximum value for reserved AWT event IDs. Programs defining
 240      * their own event IDs should use IDs greater than this value.
 241      */
 242     public static final int RESERVED_ID_MAX = 1999;
 243 
 244     // security stuff
 245     private static Field inputEvent_CanAccessSystemClipboard_Field = null;
 246 
 247     /*
 248      * JDK 1.1 serialVersionUID
 249      */
 250     private static final long serialVersionUID = -1825314779160409405L;
 251 
 252     static {
 253         /* ensure that the necessary native libraries are loaded */
 254         Toolkit.loadLibraries();
 255         if (!GraphicsEnvironment.isHeadless()) {
 256             initIDs();
 257         }
 258         AWTAccessor.setAWTEventAccessor(
 259             new AWTAccessor.AWTEventAccessor() {
 260                 public void setPosted(AWTEvent ev) {
 261                     ev.isPosted = true;
 262                 }
 263 
 264                 public void setSystemGenerated(AWTEvent ev) {
 265                     ev.isSystemGenerated = true;
 266                 }
 267 
 268                 public boolean isSystemGenerated(AWTEvent ev) {
 269                     return ev.isSystemGenerated;
 270                 }
 271 
 272                 public AccessControlContext getAccessControlContext(AWTEvent ev) {
 273                     return ev.getAccessControlContext();
 274                 }
 275 
 276                 public byte[] getBData(AWTEvent ev) {
 277                     return ev.bdata;
 278                 }
 279 
 280                 public void setBData(AWTEvent ev, byte[] bdata) {
 281                     ev.bdata = bdata;
 282                 }
 283 
 284             });
 285     }
 286 
 287     /**
 288      * Initialize JNI field and method IDs for fields that may be
 289      * accessed from C.
 290      */
 291     private static native void initIDs();
 292 
 293     /**
 294      * Constructs an AWTEvent object from the parameters of a 1.0-style event.
 295      * @param event the old-style event
 296      */
 297     public AWTEvent(Event event) {
 298         this(event.target, event.id);
 299     }
 300 
 301     /**
 302      * Constructs an AWTEvent object with the specified source object and type.
 303      *
 304      * @param source the object where the event originated
 305      * @param id the event type
 306      */
 307     public AWTEvent(Object source, int id) {
 308         super(source);
 309         this.id = id;
 310         switch(id) {
 311           case ActionEvent.ACTION_PERFORMED:
 312           case ItemEvent.ITEM_STATE_CHANGED:
 313           case AdjustmentEvent.ADJUSTMENT_VALUE_CHANGED:
 314           case TextEvent.TEXT_VALUE_CHANGED:
 315             consumed = true;
 316             break;
 317           default:
 318         }
 319     }
 320 
 321     /**
 322      * Retargets an event to a new source. This method is typically used to
 323      * retarget an event to a lightweight child Component of the original
 324      * heavyweight source.
 325      * <p>
 326      * This method is intended to be used only by event targeting subsystems,
 327      * such as client-defined KeyboardFocusManagers. It is not for general
 328      * client use.
 329      *
 330      * @param newSource the new Object to which the event should be dispatched
 331      * @since 1.4
 332      */
 333     public void setSource(Object newSource) {
 334         if (source == newSource) {
 335             return;
 336         }
 337 
 338         Component comp = null;
 339         if (newSource instanceof Component) {
 340             comp = (Component)newSource;
 341             while (comp != null && comp.peer != null &&
 342                    (comp.peer instanceof LightweightPeer)) {
 343                 comp = comp.parent;
 344             }
 345         }
 346 
 347         synchronized (this) {
 348             source = newSource;
 349             if (comp != null) {
 350                 ComponentPeer peer = comp.peer;
 351                 if (peer != null) {
 352                     nativeSetSource(peer);
 353                 }
 354             }
 355         }
 356     }
 357 
 358     private native void nativeSetSource(ComponentPeer peer);
 359 
 360     /**
 361      * Returns the event type.
 362      *
 363      * @return the event's type id
 364      */
 365     public int getID() {
 366         return id;
 367     }
 368 
 369     /**
 370      * Returns a String representation of this object.
 371      */
 372     public String toString() {
 373         String srcName = null;
 374         if (source instanceof Component) {
 375             srcName = ((Component)source).getName();
 376         } else if (source instanceof MenuComponent) {
 377             srcName = ((MenuComponent)source).getName();
 378         }
 379         return getClass().getName() + "[" + paramString() + "] on " +
 380             (srcName != null? srcName : source);
 381     }
 382 
 383     /**
 384      * Returns a string representing the state of this {@code Event}.
 385      * This method is intended to be used only for debugging purposes, and the
 386      * content and format of the returned string may vary between
 387      * implementations. The returned string may be empty but may not be
 388      * {@code null}.
 389      *
 390      * @return  a string representation of this event
 391      */
 392     public String paramString() {
 393         return "";
 394     }
 395 
 396     /**
 397      * Consumes this event, if this event can be consumed. Only low-level,
 398      * system events can be consumed
 399      */
 400     protected void consume() {
 401         switch(id) {
 402           case KeyEvent.KEY_PRESSED:
 403           case KeyEvent.KEY_RELEASED:
 404           case MouseEvent.MOUSE_PRESSED:
 405           case MouseEvent.MOUSE_RELEASED:
 406           case MouseEvent.MOUSE_MOVED:
 407           case MouseEvent.MOUSE_DRAGGED:
 408           case MouseEvent.MOUSE_ENTERED:
 409           case MouseEvent.MOUSE_EXITED:
 410           case MouseEvent.MOUSE_WHEEL:
 411           case InputMethodEvent.INPUT_METHOD_TEXT_CHANGED:
 412           case InputMethodEvent.CARET_POSITION_CHANGED:
 413               consumed = true;
 414               break;
 415           default:
 416               // event type cannot be consumed
 417         }
 418     }
 419 
 420     /**
 421      * Returns whether this event has been consumed.
 422      *
 423      * @return {@code true} if this event has been consumed;
 424      *          otherwise {@code false}
 425      */
 426     protected boolean isConsumed() {
 427         return consumed;
 428     }
 429 
 430     /**
 431      * Converts a new event to an old one (used for compatibility).
 432      * If the new event cannot be converted (because no old equivalent
 433      * exists) then this returns null.
 434      *
 435      * Note: this method is here instead of in each individual new
 436      * event class in java.awt.event because we don't want to make
 437      * it public and it needs to be called from java.awt.
 438      */
 439     Event convertToOld() {
 440         Object src = getSource();
 441         int newid = id;
 442 
 443         switch(id) {
 444           case KeyEvent.KEY_PRESSED:
 445           case KeyEvent.KEY_RELEASED:
 446               KeyEvent ke = (KeyEvent)this;
 447               if (ke.isActionKey()) {
 448                   newid = (id == KeyEvent.KEY_PRESSED?
 449                            Event.KEY_ACTION : Event.KEY_ACTION_RELEASE);
 450               }
 451               int keyCode = ke.getKeyCode();
 452               if (keyCode == KeyEvent.VK_SHIFT ||
 453                   keyCode == KeyEvent.VK_CONTROL ||
 454                   keyCode == KeyEvent.VK_ALT) {
 455                   return null;  // suppress modifier keys in old event model.
 456               }
 457               // no mask for button1 existed in old Event - strip it out
 458               return new Event(src, ke.getWhen(), newid, 0, 0,
 459                                Event.getOldEventKey(ke),
 460                                (ke.getModifiers() & ~InputEvent.BUTTON1_MASK));
 461 
 462           case MouseEvent.MOUSE_PRESSED:
 463           case MouseEvent.MOUSE_RELEASED:
 464           case MouseEvent.MOUSE_MOVED:
 465           case MouseEvent.MOUSE_DRAGGED:
 466           case MouseEvent.MOUSE_ENTERED:
 467           case MouseEvent.MOUSE_EXITED:
 468               MouseEvent me = (MouseEvent)this;
 469               // no mask for button1 existed in old Event - strip it out
 470               Event olde = new Event(src, me.getWhen(), newid,
 471                                me.getX(), me.getY(), 0,
 472                                (me.getModifiers() & ~InputEvent.BUTTON1_MASK));
 473               olde.clickCount = me.getClickCount();
 474               return olde;
 475 
 476           case FocusEvent.FOCUS_GAINED:
 477               return new Event(src, Event.GOT_FOCUS, null);
 478 
 479           case FocusEvent.FOCUS_LOST:
 480               return new Event(src, Event.LOST_FOCUS, null);
 481 
 482           case WindowEvent.WINDOW_CLOSING:
 483           case WindowEvent.WINDOW_ICONIFIED:
 484           case WindowEvent.WINDOW_DEICONIFIED:
 485               return new Event(src, newid, null);
 486 
 487           case ComponentEvent.COMPONENT_MOVED:
 488               if (src instanceof Frame || src instanceof Dialog) {
 489                   Point p = ((Component)src).getLocation();
 490                   return new Event(src, 0, Event.WINDOW_MOVED, p.x, p.y, 0, 0);
 491               }
 492               break;
 493 
 494           case ActionEvent.ACTION_PERFORMED:
 495               ActionEvent ae = (ActionEvent)this;
 496               String cmd;
 497               if (src instanceof Button) {
 498                   cmd = ((Button)src).getLabel();
 499               } else if (src instanceof MenuItem) {
 500                   cmd = ((MenuItem)src).getLabel();
 501               } else {
 502                   cmd = ae.getActionCommand();
 503               }
 504               return new Event(src, 0, newid, 0, 0, 0, ae.getModifiers(), cmd);
 505 
 506           case ItemEvent.ITEM_STATE_CHANGED:
 507               ItemEvent ie = (ItemEvent)this;
 508               Object arg;
 509               if (src instanceof List) {
 510                   newid = (ie.getStateChange() == ItemEvent.SELECTED?
 511                            Event.LIST_SELECT : Event.LIST_DESELECT);
 512                   arg = ie.getItem();
 513               } else {
 514                   newid = Event.ACTION_EVENT;
 515                   if (src instanceof Choice) {
 516                       arg = ie.getItem();
 517 
 518                   } else { // Checkbox
 519                       arg = Boolean.valueOf(ie.getStateChange() == ItemEvent.SELECTED);
 520                   }
 521               }
 522               return new Event(src, newid, arg);
 523 
 524           case AdjustmentEvent.ADJUSTMENT_VALUE_CHANGED:
 525               AdjustmentEvent aje = (AdjustmentEvent)this;
 526               switch(aje.getAdjustmentType()) {
 527                 case AdjustmentEvent.UNIT_INCREMENT:
 528                   newid = Event.SCROLL_LINE_DOWN;
 529                   break;
 530                 case AdjustmentEvent.UNIT_DECREMENT:
 531                   newid = Event.SCROLL_LINE_UP;
 532                   break;
 533                 case AdjustmentEvent.BLOCK_INCREMENT:
 534                   newid = Event.SCROLL_PAGE_DOWN;
 535                   break;
 536                 case AdjustmentEvent.BLOCK_DECREMENT:
 537                   newid = Event.SCROLL_PAGE_UP;
 538                   break;
 539                 case AdjustmentEvent.TRACK:
 540                   if (aje.getValueIsAdjusting()) {
 541                       newid = Event.SCROLL_ABSOLUTE;
 542                   }
 543                   else {
 544                       newid = Event.SCROLL_END;
 545                   }
 546                   break;
 547                 default:
 548                   return null;
 549               }
 550               return new Event(src, newid, Integer.valueOf(aje.getValue()));
 551 
 552           default:
 553         }
 554         return null;
 555     }
 556 
 557     /**
 558      * Copies all private data from this event into that.
 559      * Space is allocated for the copied data that will be
 560      * freed when the that is finalized. Upon completion,
 561      * this event is not changed.
 562      */
 563     void copyPrivateDataInto(AWTEvent that) {
 564         that.bdata = this.bdata;
 565         // Copy canAccessSystemClipboard value from this into that.
 566         if (this instanceof InputEvent && that instanceof InputEvent) {
 567 
 568             AWTAccessor.InputEventAccessor accessor
 569                     = AWTAccessor.getInputEventAccessor();
 570 
 571             boolean b = accessor.canAccessSystemClipboard((InputEvent) this);
 572             accessor.setCanAccessSystemClipboard((InputEvent) that, b);
 573         }
 574         that.isSystemGenerated = this.isSystemGenerated;
 575     }
 576 
 577     void dispatched() {
 578         if (this instanceof InputEvent) {
 579             AWTAccessor.getInputEventAccessor().
 580                     setCanAccessSystemClipboard((InputEvent) this, false);
 581         }
 582     }
 583 } // class AWTEvent