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      *
 296      * @param event the old-style event
 297      * @deprecated It is recommended that {@link #AWTEvent(Object, int)} be used
 298      *             instead
 299      */
 300     @Deprecated(since = "9")
 301     public AWTEvent(Event event) {
 302         this(event.target, event.id);
 303     }
 304 
 305     /**
 306      * Constructs an AWTEvent object with the specified source object and type.
 307      *
 308      * @param source the object where the event originated
 309      * @param id the event type
 310      */
 311     public AWTEvent(Object source, int id) {
 312         super(source);
 313         this.id = id;
 314         switch(id) {
 315           case ActionEvent.ACTION_PERFORMED:
 316           case ItemEvent.ITEM_STATE_CHANGED:
 317           case AdjustmentEvent.ADJUSTMENT_VALUE_CHANGED:
 318           case TextEvent.TEXT_VALUE_CHANGED:
 319             consumed = true;
 320             break;
 321           default:
 322         }
 323     }
 324 
 325     /**
 326      * Retargets an event to a new source. This method is typically used to
 327      * retarget an event to a lightweight child Component of the original
 328      * heavyweight source.
 329      * <p>
 330      * This method is intended to be used only by event targeting subsystems,
 331      * such as client-defined KeyboardFocusManagers. It is not for general
 332      * client use.
 333      *
 334      * @param newSource the new Object to which the event should be dispatched
 335      * @since 1.4
 336      */
 337     public void setSource(Object newSource) {
 338         if (source == newSource) {
 339             return;
 340         }
 341 
 342         Component comp = null;
 343         if (newSource instanceof Component) {
 344             comp = (Component)newSource;
 345             while (comp != null && comp.peer != null &&
 346                    (comp.peer instanceof LightweightPeer)) {
 347                 comp = comp.parent;
 348             }
 349         }
 350 
 351         synchronized (this) {
 352             source = newSource;
 353             if (comp != null) {
 354                 ComponentPeer peer = comp.peer;
 355                 if (peer != null) {
 356                     nativeSetSource(peer);
 357                 }
 358             }
 359         }
 360     }
 361 
 362     private native void nativeSetSource(ComponentPeer peer);
 363 
 364     /**
 365      * Returns the event type.
 366      *
 367      * @return the event's type id
 368      */
 369     public int getID() {
 370         return id;
 371     }
 372 
 373     /**
 374      * Returns a String representation of this object.
 375      */
 376     public String toString() {
 377         String srcName = null;
 378         if (source instanceof Component) {
 379             srcName = ((Component)source).getName();
 380         } else if (source instanceof MenuComponent) {
 381             srcName = ((MenuComponent)source).getName();
 382         }
 383         return getClass().getName() + "[" + paramString() + "] on " +
 384             (srcName != null? srcName : source);
 385     }
 386 
 387     /**
 388      * Returns a string representing the state of this {@code Event}.
 389      * This method is intended to be used only for debugging purposes, and the
 390      * content and format of the returned string may vary between
 391      * implementations. The returned string may be empty but may not be
 392      * {@code null}.
 393      *
 394      * @return  a string representation of this event
 395      */
 396     public String paramString() {
 397         return "";
 398     }
 399 
 400     /**
 401      * Consumes this event, if this event can be consumed. Only low-level,
 402      * system events can be consumed
 403      */
 404     protected void consume() {
 405         switch(id) {
 406           case KeyEvent.KEY_PRESSED:
 407           case KeyEvent.KEY_RELEASED:
 408           case MouseEvent.MOUSE_PRESSED:
 409           case MouseEvent.MOUSE_RELEASED:
 410           case MouseEvent.MOUSE_MOVED:
 411           case MouseEvent.MOUSE_DRAGGED:
 412           case MouseEvent.MOUSE_ENTERED:
 413           case MouseEvent.MOUSE_EXITED:
 414           case MouseEvent.MOUSE_WHEEL:
 415           case InputMethodEvent.INPUT_METHOD_TEXT_CHANGED:
 416           case InputMethodEvent.CARET_POSITION_CHANGED:
 417               consumed = true;
 418               break;
 419           default:
 420               // event type cannot be consumed
 421         }
 422     }
 423 
 424     /**
 425      * Returns whether this event has been consumed.
 426      *
 427      * @return {@code true} if this event has been consumed;
 428      *          otherwise {@code false}
 429      */
 430     protected boolean isConsumed() {
 431         return consumed;
 432     }
 433 
 434     /**
 435      * Converts a new event to an old one (used for compatibility).
 436      * If the new event cannot be converted (because no old equivalent
 437      * exists) then this returns null.
 438      *
 439      * Note: this method is here instead of in each individual new
 440      * event class in java.awt.event because we don't want to make
 441      * it public and it needs to be called from java.awt.
 442      */
 443     @SuppressWarnings("deprecation")
 444     Event convertToOld() {
 445         Object src = getSource();
 446         int newid = id;
 447 
 448         switch(id) {
 449           case KeyEvent.KEY_PRESSED:
 450           case KeyEvent.KEY_RELEASED:
 451               KeyEvent ke = (KeyEvent)this;
 452               if (ke.isActionKey()) {
 453                   newid = (id == KeyEvent.KEY_PRESSED?
 454                            Event.KEY_ACTION : Event.KEY_ACTION_RELEASE);
 455               }
 456               int keyCode = ke.getKeyCode();
 457               if (keyCode == KeyEvent.VK_SHIFT ||
 458                   keyCode == KeyEvent.VK_CONTROL ||
 459                   keyCode == KeyEvent.VK_ALT) {
 460                   return null;  // suppress modifier keys in old event model.
 461               }
 462               // no mask for button1 existed in old Event - strip it out
 463               return new Event(src, ke.getWhen(), newid, 0, 0,
 464                                Event.getOldEventKey(ke),
 465                                (ke.getModifiers() & ~InputEvent.BUTTON1_MASK));
 466 
 467           case MouseEvent.MOUSE_PRESSED:
 468           case MouseEvent.MOUSE_RELEASED:
 469           case MouseEvent.MOUSE_MOVED:
 470           case MouseEvent.MOUSE_DRAGGED:
 471           case MouseEvent.MOUSE_ENTERED:
 472           case MouseEvent.MOUSE_EXITED:
 473               MouseEvent me = (MouseEvent)this;
 474               // no mask for button1 existed in old Event - strip it out
 475               Event olde = new Event(src, me.getWhen(), newid,
 476                                me.getX(), me.getY(), 0,
 477                                (me.getModifiers() & ~InputEvent.BUTTON1_MASK));
 478               olde.clickCount = me.getClickCount();
 479               return olde;
 480 
 481           case FocusEvent.FOCUS_GAINED:
 482               return new Event(src, Event.GOT_FOCUS, null);
 483 
 484           case FocusEvent.FOCUS_LOST:
 485               return new Event(src, Event.LOST_FOCUS, null);
 486 
 487           case WindowEvent.WINDOW_CLOSING:
 488           case WindowEvent.WINDOW_ICONIFIED:
 489           case WindowEvent.WINDOW_DEICONIFIED:
 490               return new Event(src, newid, null);
 491 
 492           case ComponentEvent.COMPONENT_MOVED:
 493               if (src instanceof Frame || src instanceof Dialog) {
 494                   Point p = ((Component)src).getLocation();
 495                   return new Event(src, 0, Event.WINDOW_MOVED, p.x, p.y, 0, 0);
 496               }
 497               break;
 498 
 499           case ActionEvent.ACTION_PERFORMED:
 500               ActionEvent ae = (ActionEvent)this;
 501               String cmd;
 502               if (src instanceof Button) {
 503                   cmd = ((Button)src).getLabel();
 504               } else if (src instanceof MenuItem) {
 505                   cmd = ((MenuItem)src).getLabel();
 506               } else {
 507                   cmd = ae.getActionCommand();
 508               }
 509               return new Event(src, 0, newid, 0, 0, 0, ae.getModifiers(), cmd);
 510 
 511           case ItemEvent.ITEM_STATE_CHANGED:
 512               ItemEvent ie = (ItemEvent)this;
 513               Object arg;
 514               if (src instanceof List) {
 515                   newid = (ie.getStateChange() == ItemEvent.SELECTED?
 516                            Event.LIST_SELECT : Event.LIST_DESELECT);
 517                   arg = ie.getItem();
 518               } else {
 519                   newid = Event.ACTION_EVENT;
 520                   if (src instanceof Choice) {
 521                       arg = ie.getItem();
 522 
 523                   } else { // Checkbox
 524                       arg = Boolean.valueOf(ie.getStateChange() == ItemEvent.SELECTED);
 525                   }
 526               }
 527               return new Event(src, newid, arg);
 528 
 529           case AdjustmentEvent.ADJUSTMENT_VALUE_CHANGED:
 530               AdjustmentEvent aje = (AdjustmentEvent)this;
 531               switch(aje.getAdjustmentType()) {
 532                 case AdjustmentEvent.UNIT_INCREMENT:
 533                   newid = Event.SCROLL_LINE_DOWN;
 534                   break;
 535                 case AdjustmentEvent.UNIT_DECREMENT:
 536                   newid = Event.SCROLL_LINE_UP;
 537                   break;
 538                 case AdjustmentEvent.BLOCK_INCREMENT:
 539                   newid = Event.SCROLL_PAGE_DOWN;
 540                   break;
 541                 case AdjustmentEvent.BLOCK_DECREMENT:
 542                   newid = Event.SCROLL_PAGE_UP;
 543                   break;
 544                 case AdjustmentEvent.TRACK:
 545                   if (aje.getValueIsAdjusting()) {
 546                       newid = Event.SCROLL_ABSOLUTE;
 547                   }
 548                   else {
 549                       newid = Event.SCROLL_END;
 550                   }
 551                   break;
 552                 default:
 553                   return null;
 554               }
 555               return new Event(src, newid, Integer.valueOf(aje.getValue()));
 556 
 557           default:
 558         }
 559         return null;
 560     }
 561 
 562     /**
 563      * Copies all private data from this event into that.
 564      * Space is allocated for the copied data that will be
 565      * freed when the that is finalized. Upon completion,
 566      * this event is not changed.
 567      */
 568     void copyPrivateDataInto(AWTEvent that) {
 569         that.bdata = this.bdata;
 570         // Copy canAccessSystemClipboard value from this into that.
 571         if (this instanceof InputEvent && that instanceof InputEvent) {
 572 
 573             AWTAccessor.InputEventAccessor accessor
 574                     = AWTAccessor.getInputEventAccessor();
 575 
 576             boolean b = accessor.canAccessSystemClipboard((InputEvent) this);
 577             accessor.setCanAccessSystemClipboard((InputEvent) that, b);
 578         }
 579         that.isSystemGenerated = this.isSystemGenerated;
 580     }
 581 
 582     void dispatched() {
 583         if (this instanceof InputEvent) {
 584             AWTAccessor.getInputEventAccessor().
 585                     setCanAccessSystemClipboard((InputEvent) this, false);
 586         }
 587     }
 588 } // class AWTEvent