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