# HG changeset patch # User lana # Date 1260467173 28800 # Node ID 1411f4ebf52ee9071098e30e68059b27e4451bef # Parent feacdd1c5df331ebaa7668111342ebd0b44ee6e3# Parent 61cb05d6efa2132b5bfcca032a4ed7db456c1299 Merge diff -r feacdd1c5df3 -r 1411f4ebf52e jdk/make/sun/xawt/mapfile-vers --- a/jdk/make/sun/xawt/mapfile-vers Thu Dec 10 09:43:48 2009 -0800 +++ b/jdk/make/sun/xawt/mapfile-vers Thu Dec 10 09:46:13 2009 -0800 @@ -126,6 +126,8 @@ Java_sun_awt_X11_XlibWrapper_ServerVendor; Java_sun_awt_X11_XlibWrapper_VendorRelease; Java_sun_awt_X11_XlibWrapper_IsXsunKPBehavior; + Java_sun_awt_X11_XlibWrapper_IsSunKeyboard; + Java_sun_awt_X11_XlibWrapper_IsKanaKeyboard; Java_sun_awt_X11_XlibWrapper_SetToolkitErrorHandler; Java_sun_awt_X11_XlibWrapper_XSetErrorHandler; Java_sun_awt_X11_XlibWrapper_CallErrorHandler; @@ -306,6 +308,7 @@ Java_sun_awt_X11_XlibWrapper_XkbTranslateKeyCode; Java_sun_awt_X11_XlibWrapper_XGetModifierMapping; Java_sun_awt_X11_XlibWrapper_XFreeModifiermap; + Java_sun_awt_X11_XlibWrapper_XRefreshKeyboardMapping; Java_sun_awt_X11_XlibWrapper_XChangeActivePointerGrab; Java_sun_awt_X11_XlibWrapper_XNextSecondaryLoopEvent; Java_sun_awt_X11_XlibWrapper_ExitSecondaryLoop; diff -r feacdd1c5df3 -r 1411f4ebf52e jdk/src/share/classes/java/awt/Component.java --- a/jdk/src/share/classes/java/awt/Component.java Thu Dec 10 09:43:48 2009 -0800 +++ b/jdk/src/share/classes/java/awt/Component.java Thu Dec 10 09:46:13 2009 -0800 @@ -871,7 +871,7 @@ return comp.canBeFocusOwner(); } - public boolean isVisible_NoClientCode(Component comp) { + public boolean isVisible(Component comp) { return comp.isVisible_NoClientCode(); } public void setRequestFocusController @@ -885,6 +885,71 @@ public void setAppContext(Component comp, AppContext appContext) { comp.appContext = appContext; } + public Container getParent(Component comp) { + return comp.getParent_NoClientCode(); + } + public void setParent(Component comp, Container parent) { + comp.parent = parent; + } + public void setSize(Component comp, int width, int height) { + comp.width = width; + comp.height = height; + } + public Point getLocation(Component comp) { + return comp.location_NoClientCode(); + } + public void setLocation(Component comp, int x, int y) { + comp.x = x; + comp.y = y; + } + public boolean isEnabled(Component comp) { + return comp.isEnabledImpl(); + } + public boolean isDisplayable(Component comp) { + return comp.peer != null; + } + public Cursor getCursor(Component comp) { + return comp.getCursor_NoClientCode(); + } + public ComponentPeer getPeer(Component comp) { + return comp.peer; + } + public void setPeer(Component comp, ComponentPeer peer) { + comp.peer = peer; + } + public boolean isLightweight(Component comp) { + return (comp.peer instanceof LightweightPeer); + } + public boolean getIgnoreRepaint(Component comp) { + return comp.ignoreRepaint; + } + public int getWidth(Component comp) { + return comp.width; + } + public int getHeight(Component comp) { + return comp.height; + } + public int getX(Component comp) { + return comp.x; + } + public int getY(Component comp) { + return comp.y; + } + public Color getForeground(Component comp) { + return comp.foreground; + } + public Color getBackground(Component comp) { + return comp.background; + } + public void setBackground(Component comp, Color background) { + comp.background = background; + } + public Font getFont(Component comp) { + return comp.getFont_NoClientCode(); + } + public void processEvent(Component comp, AWTEvent e) { + comp.processEvent(e); + } }); } @@ -8021,7 +8086,7 @@ Container getNativeContainer() { Container p = parent; while (p != null && p.peer instanceof LightweightPeer) { - p = p.getParent(); + p = p.getParent_NoClientCode(); } return p; } diff -r feacdd1c5df3 -r 1411f4ebf52e jdk/src/share/classes/java/awt/EventDispatchThread.java --- a/jdk/src/share/classes/java/awt/EventDispatchThread.java Thu Dec 10 09:43:48 2009 -0800 +++ b/jdk/src/share/classes/java/awt/EventDispatchThread.java Thu Dec 10 09:46:13 2009 -0800 @@ -104,11 +104,8 @@ } else { stopEvent.dispatch(); } - synchronized (theQueue) { - if (theQueue.getDispatchThread() == this) { - theQueue.detachDispatchThread(); - } - } + + theQueue.detachDispatchThread(this, false); } public void stopDispatching() { @@ -142,35 +139,7 @@ } }); } finally { - /* - * This synchronized block is to secure that the event dispatch - * thread won't die in the middle of posting a new event to the - * associated event queue. It is important because we notify - * that the event dispatch thread is busy after posting a new event - * to its queue, so the EventQueue.dispatchThread reference must - * be valid at that point. - */ - synchronized (theQueue) { - if (theQueue.getDispatchThread() == this) { - theQueue.detachDispatchThread(); - } - /* - * Event dispatch thread dies in case of an uncaught exception. - * A new event dispatch thread for this queue will be started - * only if a new event is posted to it. In case if no more - * events are posted after this thread died all events that - * currently are in the queue will never be dispatched. - */ - /* - * Fix for 4648733. Check both the associated java event - * queue and the PostEventQueue. - */ - if (theQueue.peekEvent() != null || - !SunToolkit.isPostEventQueueEmpty()) { - theQueue.initDispatchThread(); - } - AWTAutoShutdown.getInstance().notifyThreadFree(this); - } + theQueue.detachDispatchThread(this, true); } } diff -r feacdd1c5df3 -r 1411f4ebf52e jdk/src/share/classes/java/awt/EventQueue.java --- a/jdk/src/share/classes/java/awt/EventQueue.java Thu Dec 10 09:43:48 2009 -0800 +++ b/jdk/src/share/classes/java/awt/EventQueue.java Thu Dec 10 09:46:13 2009 -0800 @@ -45,6 +45,9 @@ import sun.awt.EventQueueItem; import sun.awt.AWTAccessor; +import java.util.concurrent.locks.Condition; +import java.util.concurrent.locks.Lock; + /** * EventQueue is a platform-independent class * that queues events, both from the underlying peer classes @@ -127,6 +130,14 @@ */ private EventQueue previousQueue; + /* + * A single lock to synchronize the push()/pop() and related operations with + * all the EventQueues from the AppContext. Synchronization on any particular + * event queue(s) is not enough: we should lock the whole stack. + */ + private final Lock pushPopLock; + private final Condition pushPopCond; + private EventDispatchThread dispatchThread; private final ThreadGroup threadGroup = @@ -158,11 +169,11 @@ static { AWTAccessor.setEventQueueAccessor( new AWTAccessor.EventQueueAccessor() { - public EventQueue getNextQueue(EventQueue eventQueue) { - return eventQueue.nextQueue; + public Thread getDispatchThread(EventQueue eventQueue) { + return eventQueue.getDispatchThread(); } - public Thread getDispatchThread(EventQueue eventQueue) { - return eventQueue.dispatchThread; + public boolean isDispatchThreadImpl(EventQueue eventQueue) { + return eventQueue.isDispatchThreadImpl(); } }); } @@ -179,6 +190,9 @@ * may call AppContext.getAppContext() before createNewAppContext() * completes thus causing mess in thread group to appcontext mapping. */ + + pushPopLock = (Lock)AppContext.getAppContext().get(AppContext.EVENT_QUEUE_LOCK_KEY); + pushPopCond = (Condition)AppContext.getAppContext().get(AppContext.EVENT_QUEUE_COND_KEY); } /** @@ -207,7 +221,8 @@ */ final void postEventPrivate(AWTEvent theEvent) { theEvent.isPosted = true; - synchronized(this) { + pushPopLock.lock(); + try { if (dispatchThread == null && nextQueue == null) { if (theEvent.getSource() == AWTAutoShutdown.getInstance()) { return; @@ -221,6 +236,8 @@ return; } postEvent(theEvent, getPriority(theEvent)); + } finally { + pushPopLock.unlock(); } } @@ -280,9 +297,9 @@ if (theEvent.getSource() != AWTAutoShutdown.getInstance()) { AWTAutoShutdown.getInstance().notifyThreadBusy(dispatchThread); } - notifyAll(); + pushPopCond.signalAll(); } else if (notifyID) { - notifyAll(); + pushPopCond.signalAll(); } } else { // The event was not coalesced or has non-Component source. @@ -290,7 +307,7 @@ queues[priority].tail.next = newItem; queues[priority].tail = newItem; if (notifyID) { - notifyAll(); + pushPopCond.signalAll(); } } } @@ -482,7 +499,8 @@ * event queues are nested with push()/pop(). */ SunToolkit.flushPendingEvents(); - synchronized (this) { + pushPopLock.lock(); + try { for (int i = NUM_PRIORITIES - 1; i >= 0; i--) { if (queues[i].head != null) { EventQueueItem entry = queues[i].head; @@ -495,7 +513,9 @@ } } AWTAutoShutdown.getInstance().notifyThreadFree(dispatchThread); - wait(); + pushPopCond.await(); + } finally { + pushPopLock.unlock(); } } while(true); } @@ -508,7 +528,8 @@ * event queues are nested with push()/pop(). */ SunToolkit.flushPendingEvents(); - synchronized (this) { + pushPopLock.lock(); + try { for (int i = 0; i < NUM_PRIORITIES; i++) { for (EventQueueItem entry = queues[i].head, prev = null; entry != null; prev = entry, entry = entry.next) @@ -527,9 +548,11 @@ } } } - this.waitForID = id; - wait(); - this.waitForID = 0; + waitForID = id; + pushPopCond.await(); + waitForID = 0; + } finally { + pushPopLock.unlock(); } } while(true); } @@ -539,11 +562,16 @@ * without removing it. * @return the first event */ - public synchronized AWTEvent peekEvent() { - for (int i = NUM_PRIORITIES - 1; i >= 0; i--) { - if (queues[i].head != null) { - return queues[i].head.event; + public AWTEvent peekEvent() { + pushPopLock.lock(); + try { + for (int i = NUM_PRIORITIES - 1; i >= 0; i--) { + if (queues[i].head != null) { + return queues[i].head.event; + } } + } finally { + pushPopLock.unlock(); } return null; @@ -555,14 +583,19 @@ * @return the first event of the specified id or null * if there is no such event */ - public synchronized AWTEvent peekEvent(int id) { - for (int i = NUM_PRIORITIES - 1; i >= 0; i--) { - EventQueueItem q = queues[i].head; - for (; q != null; q = q.next) { - if (q.event.getID() == id) { - return q.event; + public AWTEvent peekEvent(int id) { + pushPopLock.lock(); + try { + for (int i = NUM_PRIORITIES - 1; i >= 0; i--) { + EventQueueItem q = queues[i].head; + for (; q != null; q = q.next) { + if (q.event.getID() == id) { + return q.event; + } } } + } finally { + pushPopLock.unlock(); } return null; @@ -661,17 +694,27 @@ public static long getMostRecentEventTime() { return Toolkit.getEventQueue().getMostRecentEventTimeImpl(); } - private synchronized long getMostRecentEventTimeImpl() { - return (Thread.currentThread() == dispatchThread) - ? mostRecentEventTime - : System.currentTimeMillis(); + private long getMostRecentEventTimeImpl() { + pushPopLock.lock(); + try { + return (Thread.currentThread() == dispatchThread) + ? mostRecentEventTime + : System.currentTimeMillis(); + } finally { + pushPopLock.unlock(); + } } /** * @return most recent event time on all threads. */ - synchronized long getMostRecentEventTimeEx() { - return mostRecentEventTime; + long getMostRecentEventTimeEx() { + pushPopLock.lock(); + try { + return mostRecentEventTime; + } finally { + pushPopLock.unlock(); + } } /** @@ -689,10 +732,15 @@ public static AWTEvent getCurrentEvent() { return Toolkit.getEventQueue().getCurrentEventImpl(); } - private synchronized AWTEvent getCurrentEventImpl() { - return (Thread.currentThread() == dispatchThread) - ? ((AWTEvent)currentEvent.get()) - : null; + private AWTEvent getCurrentEventImpl() { + pushPopLock.lock(); + try { + return (Thread.currentThread() == dispatchThread) + ? ((AWTEvent)currentEvent.get()) + : null; + } finally { + pushPopLock.unlock(); + } } /** @@ -706,21 +754,22 @@ * @throws NullPointerException if newEventQueue is null * @since 1.2 */ - public synchronized void push(EventQueue newEventQueue) { + public void push(EventQueue newEventQueue) { if (eventLog.isLoggable(PlatformLogger.FINE)) { eventLog.fine("EventQueue.push(" + newEventQueue + ")"); } - if (nextQueue != null) { - nextQueue.push(newEventQueue); - return; - } + pushPopLock.lock(); + try { + EventQueue toPush = this; + while (toPush.nextQueue != null) { + toPush = toPush.nextQueue; + } - synchronized (newEventQueue) { // Transfer all events forward to new EventQueue. - while (peekEvent() != null) { + while (toPush.peekEvent() != null) { try { - newEventQueue.postEventPrivate(getNextEvent()); + newEventQueue.postEventPrivate(toPush.getNextEvent()); } catch (InterruptedException ie) { if (eventLog.isLoggable(PlatformLogger.FINE)) { eventLog.fine("Interrupted push", ie); @@ -728,27 +777,30 @@ } } - newEventQueue.previousQueue = this; - } - /* - * Stop the event dispatch thread associated with the currently - * active event queue, so that after the new queue is pushed - * on the top this event dispatch thread won't prevent AWT from - * being automatically shut down. - * Use stopDispatchingLater() to avoid deadlock: stopDispatching() - * waits for the dispatch thread to exit, so if the dispatch - * thread attempts to synchronize on this EventQueue object - * it will never exit since we already hold this lock. - */ - if (dispatchThread != null) { - dispatchThread.stopDispatchingLater(); - } + newEventQueue.previousQueue = toPush; - nextQueue = newEventQueue; + /* + * Stop the event dispatch thread associated with the currently + * active event queue, so that after the new queue is pushed + * on the top this event dispatch thread won't prevent AWT from + * being automatically shut down. + * Use stopDispatchingLater() to avoid deadlock: stopDispatching() + * waits for the dispatch thread to exit, which in turn waits + * for the lock in EQ.detachDispatchThread(), which is hold by + * this method. + */ + if (toPush.dispatchThread != null) { + toPush.dispatchThread.stopDispatchingLater(); + } - AppContext appContext = AppContext.getAppContext(); - if (appContext.get(AppContext.EVENT_QUEUE_KEY) == this) { - appContext.put(AppContext.EVENT_QUEUE_KEY, newEventQueue); + toPush.nextQueue = newEventQueue; + + AppContext appContext = AppContext.getAppContext(); + if (appContext.get(AppContext.EVENT_QUEUE_KEY) == toPush) { + appContext.put(AppContext.EVENT_QUEUE_KEY, newEventQueue); + } + } finally { + pushPopLock.unlock(); } } @@ -770,25 +822,24 @@ eventLog.fine("EventQueue.pop(" + this + ")"); } - // To prevent deadlock, we lock on the previous EventQueue before - // this one. This uses the same locking order as everything else - // in EventQueue.java, so deadlock isn't possible. - EventQueue prev = previousQueue; - synchronized ((prev != null) ? prev : this) { - synchronized(this) { - if (nextQueue != null) { - nextQueue.pop(); - return; + EventDispatchThread dt = null; + pushPopLock.lock(); + try { + EventQueue toPop = this; + while (toPop.nextQueue != null) { + toPop = toPop.nextQueue; } - if (previousQueue == null) { + EventQueue prev = toPop.previousQueue; + if (prev == null) { throw new EmptyStackException(); } + toPop.previousQueue = null; // Transfer all events back to previous EventQueue. - previousQueue.nextQueue = null; - while (peekEvent() != null) { + prev.nextQueue = null; + while (toPop.peekEvent() != null) { try { - previousQueue.postEventPrivate(getNextEvent()); + prev.postEventPrivate(toPop.getNextEvent()); } catch (InterruptedException ie) { if (eventLog.isLoggable(PlatformLogger.FINE)) { eventLog.fine("Interrupted pop", ie); @@ -797,14 +848,14 @@ } AppContext appContext = AppContext.getAppContext(); if (appContext.get(AppContext.EVENT_QUEUE_KEY) == this) { - appContext.put(AppContext.EVENT_QUEUE_KEY, previousQueue); + appContext.put(AppContext.EVENT_QUEUE_KEY, prev); } - previousQueue = null; - } + dt = toPop.dispatchThread; + } finally { + pushPopLock.unlock(); } - EventDispatchThread dt = this.dispatchThread; if (dt != null) { dt.stopDispatching(); // Must be done outside synchronized // block to avoid possible deadlock @@ -833,16 +884,27 @@ */ public static boolean isDispatchThread() { EventQueue eq = Toolkit.getEventQueue(); - EventQueue next = eq.nextQueue; - while (next != null) { - eq = next; - next = eq.nextQueue; + return eq.isDispatchThreadImpl(); + } + + final boolean isDispatchThreadImpl() { + EventQueue eq = this; + pushPopLock.lock(); + try { + EventQueue next = eq.nextQueue; + while (next != null) { + eq = next; + next = eq.nextQueue; + } + return (Thread.currentThread() == eq.dispatchThread); + } finally { + pushPopLock.unlock(); } - return (Thread.currentThread() == eq.dispatchThread); } final void initDispatchThread() { - synchronized (this) { + pushPopLock.lock(); + try { AppContext appContext = AppContext.getAppContext(); if (dispatchThread == null && !threadGroup.isDestroyed() && !appContext.isDisposed()) { dispatchThread = (EventDispatchThread) @@ -861,11 +923,45 @@ AWTAutoShutdown.getInstance().notifyThreadBusy(dispatchThread); dispatchThread.start(); } + } finally { + pushPopLock.unlock(); } } - final void detachDispatchThread() { - dispatchThread = null; + final void detachDispatchThread(EventDispatchThread edt, boolean restart) { + /* + * This synchronized block is to secure that the event dispatch + * thread won't die in the middle of posting a new event to the + * associated event queue. It is important because we notify + * that the event dispatch thread is busy after posting a new event + * to its queue, so the EventQueue.dispatchThread reference must + * be valid at that point. + */ + pushPopLock.lock(); + try { + EventDispatchThread oldDispatchThread = dispatchThread; + if (dispatchThread == edt) { + dispatchThread = null; + } + if (restart) { + /* + * Event dispatch thread dies in case of an uncaught exception. + * A new event dispatch thread for this queue will be started + * only if a new event is posted to it. In case if no more + * events are posted after this thread died all events that + * currently are in the queue will never be dispatched. + * + * Fix for 4648733. Check both the associated java event + * queue and the PostEventQueue. + */ + if ((peekEvent() != null) || !SunToolkit.isPostEventQueueEmpty()) { + initDispatchThread(); + } + AWTAutoShutdown.getInstance().notifyThreadFree(oldDispatchThread); + } + } finally { + pushPopLock.unlock(); + } } /* @@ -878,7 +974,12 @@ * @see java.awt.EventQueue#detachDispatchThread */ final EventDispatchThread getDispatchThread() { - return dispatchThread; + pushPopLock.lock(); + try { + return dispatchThread; + } finally { + pushPopLock.unlock(); + } } /* @@ -895,7 +996,8 @@ */ final void removeSourceEvents(Object source, boolean removeAllEvents) { SunToolkit.flushPendingEvents(); - synchronized (this) { + pushPopLock.lock(); + try { for (int i = 0; i < NUM_PRIORITIES; i++) { EventQueueItem entry = queues[i].head; EventQueueItem prev = null; @@ -928,43 +1030,49 @@ } queues[i].tail = prev; } + } finally { + pushPopLock.unlock(); } } static void setCurrentEventAndMostRecentTime(AWTEvent e) { Toolkit.getEventQueue().setCurrentEventAndMostRecentTimeImpl(e); } - private synchronized void setCurrentEventAndMostRecentTimeImpl(AWTEvent e) - { - if (Thread.currentThread() != dispatchThread) { - return; - } + private void setCurrentEventAndMostRecentTimeImpl(AWTEvent e) { + pushPopLock.lock(); + try { + if (Thread.currentThread() != dispatchThread) { + return; + } - currentEvent = new WeakReference(e); + currentEvent = new WeakReference(e); - // This series of 'instanceof' checks should be replaced with a - // polymorphic type (for example, an interface which declares a - // getWhen() method). However, this would require us to make such - // a type public, or to place it in sun.awt. Both of these approaches - // have been frowned upon. So for now, we hack. - // - // In tiger, we will probably give timestamps to all events, so this - // will no longer be an issue. - long mostRecentEventTime2 = Long.MIN_VALUE; - if (e instanceof InputEvent) { - InputEvent ie = (InputEvent)e; - mostRecentEventTime2 = ie.getWhen(); - } else if (e instanceof InputMethodEvent) { - InputMethodEvent ime = (InputMethodEvent)e; - mostRecentEventTime2 = ime.getWhen(); - } else if (e instanceof ActionEvent) { - ActionEvent ae = (ActionEvent)e; - mostRecentEventTime2 = ae.getWhen(); - } else if (e instanceof InvocationEvent) { - InvocationEvent ie = (InvocationEvent)e; - mostRecentEventTime2 = ie.getWhen(); + // This series of 'instanceof' checks should be replaced with a + // polymorphic type (for example, an interface which declares a + // getWhen() method). However, this would require us to make such + // a type public, or to place it in sun.awt. Both of these approaches + // have been frowned upon. So for now, we hack. + // + // In tiger, we will probably give timestamps to all events, so this + // will no longer be an issue. + long mostRecentEventTime2 = Long.MIN_VALUE; + if (e instanceof InputEvent) { + InputEvent ie = (InputEvent)e; + mostRecentEventTime2 = ie.getWhen(); + } else if (e instanceof InputMethodEvent) { + InputMethodEvent ime = (InputMethodEvent)e; + mostRecentEventTime2 = ime.getWhen(); + } else if (e instanceof ActionEvent) { + ActionEvent ae = (ActionEvent)e; + mostRecentEventTime2 = ae.getWhen(); + } else if (e instanceof InvocationEvent) { + InvocationEvent ie = (InvocationEvent)e; + mostRecentEventTime2 = ie.getWhen(); + } + mostRecentEventTime = Math.max(mostRecentEventTime, mostRecentEventTime2); + } finally { + pushPopLock.unlock(); } - mostRecentEventTime = Math.max(mostRecentEventTime, mostRecentEventTime2); } /** @@ -1045,15 +1153,18 @@ * or starts a new one otherwise. */ private void wakeup(boolean isShutdown) { - synchronized(this) { + pushPopLock.lock(); + try { if (nextQueue != null) { // Forward call to the top of EventQueue stack. nextQueue.wakeup(isShutdown); } else if (dispatchThread != null) { - notifyAll(); + pushPopCond.signalAll(); } else if (!isShutdown) { initDispatchThread(); } + } finally { + pushPopLock.unlock(); } } } diff -r feacdd1c5df3 -r 1411f4ebf52e jdk/src/share/classes/java/awt/KeyboardFocusManager.java --- a/jdk/src/share/classes/java/awt/KeyboardFocusManager.java Thu Dec 10 09:43:48 2009 -0800 +++ b/jdk/src/share/classes/java/awt/KeyboardFocusManager.java Thu Dec 10 09:46:13 2009 -0800 @@ -53,8 +53,7 @@ import java.util.StringTokenizer; import java.util.WeakHashMap; -import java.util.logging.Level; -import java.util.logging.Logger; +import sun.util.logging.PlatformLogger; import sun.awt.AppContext; import sun.awt.HeadlessToolkit; @@ -111,7 +110,7 @@ { // Shared focus engine logger - private static final Logger focusLog = Logger.getLogger("java.awt.focus.KeyboardFocusManager"); + private static final PlatformLogger focusLog = PlatformLogger.getLogger("java.awt.focus.KeyboardFocusManager"); static { /* ensure that the necessary native libraries are loaded */ @@ -154,7 +153,7 @@ */ private static native void initIDs(); - private static final Logger log = Logger.getLogger("java.awt.KeyboardFocusManager"); + private static final PlatformLogger log = PlatformLogger.getLogger("java.awt.KeyboardFocusManager"); /** * The identifier for the Forward focus traversal keys. @@ -504,8 +503,8 @@ if (this == getCurrentKeyboardFocusManager()) { return focusOwner; } else { - if (focusLog.isLoggable(Level.FINER)) { - focusLog.log(Level.FINER, "This manager is " + this + ", current is " + getCurrentKeyboardFocusManager()); + if (focusLog.isLoggable(PlatformLogger.FINER)) { + focusLog.finer("This manager is " + this + ", current is " + getCurrentKeyboardFocusManager()); } throw new SecurityException(notPrivileged); } @@ -609,9 +608,9 @@ } void setNativeFocusOwner(Component comp) { - if (focusLog.isLoggable(Level.FINEST)) { - focusLog.log(Level.FINEST, "Calling peer {0} setCurrentFocusOwner for {1}", - new Object[] {String.valueOf(peer), String.valueOf(comp)}); + if (focusLog.isLoggable(PlatformLogger.FINEST)) { + focusLog.finest("Calling peer {0} setCurrentFocusOwner for {1}", + String.valueOf(peer), String.valueOf(comp)); } peer.setCurrentFocusOwner(comp); } @@ -673,8 +672,8 @@ if (this == getCurrentKeyboardFocusManager()) { return permanentFocusOwner; } else { - if (focusLog.isLoggable(Level.FINER)) { - focusLog.log(Level.FINER, "This manager is " + this + ", current is " + getCurrentKeyboardFocusManager()); + if (focusLog.isLoggable(PlatformLogger.FINER)) { + focusLog.finer("This manager is " + this + ", current is " + getCurrentKeyboardFocusManager()); } throw new SecurityException(notPrivileged); } @@ -781,8 +780,8 @@ if (this == getCurrentKeyboardFocusManager()) { return focusedWindow; } else { - if (focusLog.isLoggable(Level.FINER)) { - focusLog.log(Level.FINER, "This manager is " + this + ", current is " + getCurrentKeyboardFocusManager()); + if (focusLog.isLoggable(PlatformLogger.FINER)) { + focusLog.finer("This manager is " + this + ", current is " + getCurrentKeyboardFocusManager()); } throw new SecurityException(notPrivileged); } @@ -885,8 +884,8 @@ if (this == getCurrentKeyboardFocusManager()) { return activeWindow; } else { - if (focusLog.isLoggable(Level.FINER)) { - focusLog.log(Level.FINER, "This manager is " + this + ", current is " + getCurrentKeyboardFocusManager()); + if (focusLog.isLoggable(PlatformLogger.FINER)) { + focusLog.finer("This manager is " + this + ", current is " + getCurrentKeyboardFocusManager()); } throw new SecurityException(notPrivileged); } @@ -919,8 +918,8 @@ Window oldActiveWindow; synchronized (KeyboardFocusManager.class) { oldActiveWindow = getActiveWindow(); - if (focusLog.isLoggable(Level.FINER)) { - focusLog.log(Level.FINER, "Setting global active window to " + activeWindow + ", old active " + oldActiveWindow); + if (focusLog.isLoggable(PlatformLogger.FINER)) { + focusLog.finer("Setting global active window to " + activeWindow + ", old active " + oldActiveWindow); } try { @@ -1215,8 +1214,8 @@ if (this == getCurrentKeyboardFocusManager()) { return currentFocusCycleRoot; } else { - if (focusLog.isLoggable(Level.FINER)) { - focusLog.log(Level.FINER, "This manager is " + this + ", current is " + getCurrentKeyboardFocusManager()); + if (focusLog.isLoggable(PlatformLogger.FINER)) { + focusLog.finer("This manager is " + this + ", current is " + getCurrentKeyboardFocusManager()); } throw new SecurityException(notPrivileged); } @@ -2149,9 +2148,9 @@ HeavyweightFocusRequest(Component heavyweight, Component descendant, boolean temporary, CausedFocusEvent.Cause cause) { - if (log.isLoggable(Level.FINE)) { + if (log.isLoggable(PlatformLogger.FINE)) { if (heavyweight == null) { - log.log(Level.FINE, "Assertion (heavyweight != null) failed"); + log.fine("Assertion (heavyweight != null) failed"); } } @@ -2161,12 +2160,12 @@ } boolean addLightweightRequest(Component descendant, boolean temporary, CausedFocusEvent.Cause cause) { - if (log.isLoggable(Level.FINE)) { + if (log.isLoggable(PlatformLogger.FINE)) { if (this == HeavyweightFocusRequest.CLEAR_GLOBAL_FOCUS_OWNER) { - log.log(Level.FINE, "Assertion (this != HeavyweightFocusRequest.CLEAR_GLOBAL_FOCUS_OWNER) failed"); + log.fine("Assertion (this != HeavyweightFocusRequest.CLEAR_GLOBAL_FOCUS_OWNER) failed"); } if (descendant == null) { - log.log(Level.FINE, "Assertion (descendant != null) failed"); + log.fine("Assertion (descendant != null) failed"); } } @@ -2339,12 +2338,12 @@ (Component heavyweight, Component descendant, boolean temporary, boolean focusedWindowChangeAllowed, long time, CausedFocusEvent.Cause cause) { - if (log.isLoggable(Level.FINE)) { + if (log.isLoggable(PlatformLogger.FINE)) { if (heavyweight == null) { - log.log(Level.FINE, "Assertion (heavyweight != null) failed"); + log.fine("Assertion (heavyweight != null) failed"); } if (time == 0) { - log.log(Level.FINE, "Assertion (time != 0) failed"); + log.fine("Assertion (time != 0) failed"); } } @@ -2361,31 +2360,31 @@ Component currentFocusOwner = thisManager.getGlobalFocusOwner(); Component nativeFocusOwner = thisManager.getNativeFocusOwner(); Window nativeFocusedWindow = thisManager.getNativeFocusedWindow(); - if (focusLog.isLoggable(Level.FINER)) { - focusLog.log(Level.FINER, "SNFH for {0} in {1}", - new Object[] {String.valueOf(descendant), String.valueOf(heavyweight)}); + if (focusLog.isLoggable(PlatformLogger.FINER)) { + focusLog.finer("SNFH for {0} in {1}", + String.valueOf(descendant), String.valueOf(heavyweight)); } - if (focusLog.isLoggable(Level.FINEST)) { - focusLog.log(Level.FINEST, "0. Current focus owner {0}", - String.valueOf(currentFocusOwner)); - focusLog.log(Level.FINEST, "0. Native focus owner {0}", - String.valueOf(nativeFocusOwner)); - focusLog.log(Level.FINEST, "0. Native focused window {0}", - String.valueOf(nativeFocusedWindow)); + if (focusLog.isLoggable(PlatformLogger.FINEST)) { + focusLog.finest("0. Current focus owner {0}", + String.valueOf(currentFocusOwner)); + focusLog.finest("0. Native focus owner {0}", + String.valueOf(nativeFocusOwner)); + focusLog.finest("0. Native focused window {0}", + String.valueOf(nativeFocusedWindow)); } synchronized (heavyweightRequests) { HeavyweightFocusRequest hwFocusRequest = getLastHWRequest(); - if (focusLog.isLoggable(Level.FINEST)) { - focusLog.log(Level.FINEST, "Request {0}", String.valueOf(hwFocusRequest)); + if (focusLog.isLoggable(PlatformLogger.FINEST)) { + focusLog.finest("Request {0}", String.valueOf(hwFocusRequest)); } if (hwFocusRequest == null && heavyweight == nativeFocusOwner) { if (descendant == currentFocusOwner) { // Redundant request. - if (focusLog.isLoggable(Level.FINEST)) - focusLog.log(Level.FINEST, "1. SNFH_FAILURE for {0}", - String.valueOf(descendant)); + if (focusLog.isLoggable(PlatformLogger.FINEST)) + focusLog.finest("1. SNFH_FAILURE for {0}", + String.valueOf(descendant)); return SNFH_FAILURE; } @@ -2417,8 +2416,8 @@ // SunToolkit.postPriorityEvent(newFocusOwnerEvent); SunToolkit.postEvent(descendant.appContext, newFocusOwnerEvent); - if (focusLog.isLoggable(Level.FINEST)) - focusLog.log(Level.FINEST, "2. SNFH_HANDLED for {0}", String.valueOf(descendant)); + if (focusLog.isLoggable(PlatformLogger.FINEST)) + focusLog.finest("2. SNFH_HANDLED for {0}", String.valueOf(descendant)); return SNFH_SUCCESS_HANDLED; } else if (hwFocusRequest != null && hwFocusRequest.heavyweight == heavyweight) { @@ -2431,7 +2430,7 @@ manager.enqueueKeyEvents(time, descendant); } - if (focusLog.isLoggable(Level.FINEST)) + if (focusLog.isLoggable(PlatformLogger.FINEST)) focusLog.finest("3. SNFH_HANDLED for lightweight" + descendant + " in " + heavyweight); return SNFH_SUCCESS_HANDLED; @@ -2454,7 +2453,7 @@ (hwFocusRequest != null) ? hwFocusRequest.heavyweight : nativeFocusedWindow)) { - if (focusLog.isLoggable(Level.FINEST)) + if (focusLog.isLoggable(PlatformLogger.FINEST)) focusLog.finest("4. SNFH_FAILURE for " + descendant); return SNFH_FAILURE; } @@ -2464,7 +2463,7 @@ heavyweightRequests.add (new HeavyweightFocusRequest(heavyweight, descendant, temporary, cause)); - if (focusLog.isLoggable(Level.FINEST)) + if (focusLog.isLoggable(PlatformLogger.FINEST)) focusLog.finest("5. SNFH_PROCEED for " + descendant); return SNFH_SUCCESS_PROCEED; } @@ -2855,14 +2854,14 @@ } KeyboardFocusManager manager = getCurrentKeyboardFocusManager(); - if (focusLog.isLoggable(Level.FINER)) { + if (focusLog.isLoggable(PlatformLogger.FINER)) { if (event instanceof FocusEvent || event instanceof WindowEvent) { - focusLog.log(Level.FINER, ">>> {0}", new Object[] {String.valueOf(event)}); + focusLog.finer(">>> {0}", String.valueOf(event)); } - if (focusLog.isLoggable(Level.FINER) && event instanceof KeyEvent) { - focusLog.log(Level.FINER, " focus owner is {0}", - new Object[] {String.valueOf(manager.getGlobalFocusOwner())}); - focusLog.log(Level.FINER, ">>> {0}", new Object[] {String.valueOf(event)}); + if (focusLog.isLoggable(PlatformLogger.FINER) && event instanceof KeyEvent) { + focusLog.finer(" focus owner is {0}", + String.valueOf(manager.getGlobalFocusOwner())); + focusLog.finer(">>> {0}", String.valueOf(event)); } } @@ -2946,9 +2945,9 @@ } } static void removeLastFocusRequest(Component heavyweight) { - if (log.isLoggable(Level.FINE)) { + if (log.isLoggable(PlatformLogger.FINE)) { if (heavyweight == null) { - log.log(Level.FINE, "Assertion (heavyweight != null) failed"); + log.fine("Assertion (heavyweight != null) failed"); } } diff -r feacdd1c5df3 -r 1411f4ebf52e jdk/src/share/classes/java/awt/Window.java --- a/jdk/src/share/classes/java/awt/Window.java Thu Dec 10 09:43:48 2009 -0800 +++ b/jdk/src/share/classes/java/awt/Window.java Thu Dec 10 09:46:13 2009 -0800 @@ -148,6 +148,51 @@ public class Window extends Container implements Accessible { /** + * Enumeration of available window types. + * + * A window type defines the generic visual appearance and behavior of a + * top-level window. For example, the type may affect the kind of + * decorations of a decorated {@code Frame} or {@code Dialog} instance. + *

+ * Some platforms may not fully support a certain window type. Depending on + * the level of support, some properties of the window type may be + * disobeyed. + * + * @see #getType + * @see #setType + * @since 1.7 + */ + public static enum Type { + /** + * Represents a normal window. + * + * This is the default type for objects of the {@code Window} class or + * its descendants. Use this type for regular top-level windows. + */ + NORMAL, + + /** + * Represents a utility window. + * + * A utility window is usually a small window such as a toolbar or a + * palette. The native system may render the window with smaller + * title-bar if the window is either a {@code Frame} or a {@code + * Dialog} object, and if it has its decorations enabled. + */ + UTILITY, + + /** + * Represents a popup window. + * + * A popup window is a temporary window such as a drop-down menu or a + * tooltip. On some platforms, windows of that type may be forcibly + * made undecorated even if they are instances of the {@code Frame} or + * {@code Dialog} class, and have decorations enabled. + */ + POPUP + } + + /** * This represents the warning message that is * to be displayed in a non secure window. ie : * a window that has a security manager installed for @@ -2718,6 +2763,52 @@ } /** + * Window type. + * + * Synchronization: ObjectLock + */ + private Type type = Type.NORMAL; + + /** + * Sets the type of the window. + * + * This method can only be called while the window is not displayable. + * + * @throws IllegalComponentStateException if the window + * is displayable. + * @throws IllegalArgumentException if the type is {@code null} + * @see Component#isDisplayable + * @see #getType + * @since 1.7 + */ + public void setType(Type type) { + if (type == null) { + throw new IllegalArgumentException("type should not be null."); + } + synchronized (getTreeLock()) { + if (isDisplayable()) { + throw new IllegalComponentStateException( + "The window is displayable."); + } + synchronized (getObjectLock()) { + this.type = type; + } + } + } + + /** + * Returns the type of the window. + * + * @see #setType + * @since 1.7 + */ + public Type getType() { + synchronized (getObjectLock()) { + return type; + } + } + + /** * The window serialized data version. * * @serial @@ -3873,6 +3964,18 @@ public void setLWRequestStatus(Window changed, boolean status) { changed.syncLWRequests = status; } + + public boolean isAutoRequestFocus(Window w) { + return w.autoRequestFocus; + } + + public boolean isTrayIconWindow(Window w) { + return w.isTrayIconWindow; + } + + public void setTrayIconWindow(Window w, boolean isTrayIconWindow) { + w.isTrayIconWindow = isTrayIconWindow; + } }); // WindowAccessor } // static diff -r feacdd1c5df3 -r 1411f4ebf52e jdk/src/share/classes/javax/swing/Popup.java --- a/jdk/src/share/classes/javax/swing/Popup.java Thu Dec 10 09:43:48 2009 -0800 +++ b/jdk/src/share/classes/javax/swing/Popup.java Thu Dec 10 09:46:13 2009 -0800 @@ -227,12 +227,8 @@ HeavyWeightWindow(Window parent) { super(parent); setFocusableWindowState(false); - Toolkit tk = Toolkit.getDefaultToolkit(); - if (tk instanceof SunToolkit) { - // all the short-lived windows like Popups should be - // OverrideRedirect on X11 platforms - ((SunToolkit)tk).setOverrideRedirect(this); - } + setType(Window.Type.POPUP); + // Popups are typically transient and most likely won't benefit // from true double buffering. Turn it off here. getRootPane().setUseTrueDoubleBuffering(false); diff -r feacdd1c5df3 -r 1411f4ebf52e jdk/src/share/classes/sun/awt/AWTAccessor.java --- a/jdk/src/share/classes/sun/awt/AWTAccessor.java Thu Dec 10 09:43:48 2009 -0800 +++ b/jdk/src/share/classes/sun/awt/AWTAccessor.java Thu Dec 10 09:46:13 2009 -0800 @@ -98,7 +98,7 @@ * Returns whether the component is visible without invoking * any client code. */ - boolean isVisible_NoClientCode(Component comp); + boolean isVisible(Component comp); /** * Sets the RequestFocusController. @@ -114,6 +114,112 @@ * Sets the appContext of the component. */ void setAppContext(Component comp, AppContext appContext); + + /** + * Returns the parent of the component. + */ + Container getParent(Component comp); + + /** + * Sets the parent of the component to the specified parent. + */ + void setParent(Component comp, Container parent); + + /** + * Resizes the component to the specified width and height. + */ + void setSize(Component comp, int width, int height); + + /** + * Returns the location of the component. + */ + Point getLocation(Component comp); + + /** + * Moves the component to the new location. + */ + void setLocation(Component comp, int x, int y); + + /** + * Determines whether this component is enabled. + */ + boolean isEnabled(Component comp); + + /** + * Determines whether this component is displayable. + */ + boolean isDisplayable(Component comp); + + /** + * Gets the cursor set in the component. + */ + Cursor getCursor(Component comp); + + /** + * Returns the peer of the component. + */ + ComponentPeer getPeer(Component comp); + + /** + * Sets the peer of the component to the specified peer. + */ + void setPeer(Component comp, ComponentPeer peer); + + /** + * Determines whether this component is lightweight. + */ + boolean isLightweight(Component comp); + + /** + * Returns whether or not paint messages received from + * the operating system should be ignored. + */ + boolean getIgnoreRepaint(Component comp); + + /** + * Returns the width of the component. + */ + int getWidth(Component comp); + + /** + * Returns the height of the component. + */ + int getHeight(Component comp); + + /** + * Returns the x coordinate of the component. + */ + int getX(Component comp); + + /** + * Returns the y coordinate of the component. + */ + int getY(Component comp); + + /** + * Gets the foreground color of this component. + */ + Color getForeground(Component comp); + + /** + * Gets the background color of this component. + */ + Color getBackground(Component comp); + + /** + * Sets the background of this component to the specified color. + */ + void setBackground(Component comp, Color background); + + /** + * Gets the font of the component. + */ + Font getFont(Component comp); + + /** + * Processes events occurring on this component. + */ + void processEvent(Component comp, AWTEvent e); } /* @@ -169,6 +275,22 @@ * components in the specified window to the specified value. */ void setLWRequestStatus(Window changed, boolean status); + + /** + * Indicates whether this window should receive focus on subsequently + * being shown, or being moved to the front. + */ + boolean isAutoRequestFocus(Window w); + + /** + * Indicates whether the specified window is an utility window for TrayIcon. + */ + boolean isTrayIconWindow(Window w); + + /** + * Marks the specified window as an utility window for TrayIcon. + */ + void setTrayIconWindow(Window w, boolean isTrayIconWindow); } /* @@ -249,13 +371,13 @@ */ public interface EventQueueAccessor { /* - * Gets the next event queue. - */ - EventQueue getNextQueue(EventQueue eventQueue); - /* * Gets the event dispatch thread. */ Thread getDispatchThread(EventQueue eventQueue); + /* + * Checks if the current thread is EDT for the given EQ. + */ + public boolean isDispatchThreadImpl(EventQueue eventQueue); } /* diff -r feacdd1c5df3 -r 1411f4ebf52e jdk/src/share/classes/sun/awt/AppContext.java --- a/jdk/src/share/classes/sun/awt/AppContext.java Thu Dec 10 09:43:48 2009 -0800 +++ b/jdk/src/share/classes/sun/awt/AppContext.java Thu Dec 10 09:46:13 2009 -0800 @@ -43,6 +43,9 @@ import java.beans.PropertyChangeSupport; import java.beans.PropertyChangeListener; import sun.util.logging.PlatformLogger; +import java.util.concurrent.locks.Condition; +import java.util.concurrent.locks.Lock; +import java.util.concurrent.locks.ReentrantLock; /** * The AppContext is a table referenced by ThreadGroup which stores @@ -132,10 +135,17 @@ /* Since the contents of an AppContext are unique to each Java * session, this class should never be serialized. */ - /* The key to put()/get() the Java EventQueue into/from the AppContext. + /* + * The key to put()/get() the Java EventQueue into/from the AppContext. */ public static final Object EVENT_QUEUE_KEY = new StringBuffer("EventQueue"); + /* + * The keys to store EventQueue push/pop lock and condition. + */ + public final static Object EVENT_QUEUE_LOCK_KEY = new StringBuilder("EventQueue.Lock"); + public final static Object EVENT_QUEUE_COND_KEY = new StringBuilder("EventQueue.Condition"); + /* A map of AppContexts, referenced by ThreadGroup. */ private static final Map threadGroup2appContext = @@ -244,6 +254,13 @@ return Thread.currentThread().getContextClassLoader(); } }); + + // Initialize push/pop lock and its condition to be used by all the + // EventQueues within this AppContext + Lock eventQueuePushPopLock = new ReentrantLock(); + put(EVENT_QUEUE_LOCK_KEY, eventQueuePushPopLock); + Condition eventQueuePushPopCond = eventQueuePushPopLock.newCondition(); + put(EVENT_QUEUE_COND_KEY, eventQueuePushPopCond); } private static final ThreadLocal threadAppContext = diff -r feacdd1c5df3 -r 1411f4ebf52e jdk/src/share/classes/sun/awt/ComponentAccessor.java --- a/jdk/src/share/classes/sun/awt/ComponentAccessor.java Thu Dec 10 09:43:48 2009 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,483 +0,0 @@ -/* - * Copyright 2002-2007 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Sun designates this - * particular file as subject to the "Classpath" exception as provided - * by Sun in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, - * CA 95054 USA or visit www.sun.com if you need additional information or - * have any questions. - */ - -package sun.awt; - -import java.awt.Component; -import java.awt.Container; -import java.awt.AWTEvent; -import java.awt.Font; -import java.awt.Color; -import java.awt.Cursor; -import java.awt.Point; - -import java.awt.peer.ComponentPeer; - -import java.lang.reflect.Field; -import java.lang.reflect.Method; -import java.lang.reflect.InvocationTargetException; - -import sun.util.logging.PlatformLogger; - -import java.security.AccessController; -import java.security.PrivilegedAction; - -/** - * A collection of methods for modifying package private fields in AWT components. - * This class is meant to be used by Peer code only. Previously peer code - * got around this problem by modifying fields from native code. However - * as we move away from native code to Pure-java peers we need this class. - * - * @author Bino George - */ - - -public class ComponentAccessor -{ - private static Class componentClass; - private static Field fieldX; - private static Field fieldY; - private static Field fieldWidth; - private static Field fieldHeight; - private static Method methodGetParentNoClientCode; - private static Method methodGetFontNoClientCode; - private static Method methodProcessEvent; - private static Method methodEnableEvents; - private static Field fieldParent; - private static Field fieldBackground; - private static Field fieldForeground; - private static Field fieldFont; - private static Field fieldPacked; - private static Field fieldIgnoreRepaint; - private static Field fieldPeer; - private static Field fieldVisible; - private static Method methodIsEnabledImpl; - private static Method methodGetCursorNoClientCode; - private static Method methodLocationNoClientCode; - - private static final PlatformLogger log = PlatformLogger.getLogger("sun.awt.ComponentAccessor"); - - private ComponentAccessor() { - } - - static { - AccessController.doPrivileged( new PrivilegedAction() { - public Object run() { - try { - componentClass = Class.forName("java.awt.Component"); - fieldX = componentClass.getDeclaredField("x"); - fieldX.setAccessible(true); - fieldY = componentClass.getDeclaredField("y"); - fieldY.setAccessible(true); - fieldWidth = componentClass.getDeclaredField("width"); - fieldWidth.setAccessible(true); - fieldHeight = componentClass.getDeclaredField("height"); - fieldHeight.setAccessible(true); - fieldForeground = componentClass.getDeclaredField("foreground"); - fieldForeground.setAccessible(true); - fieldBackground = componentClass.getDeclaredField("background"); - fieldBackground.setAccessible(true); - fieldFont = componentClass.getDeclaredField("font"); - fieldFont.setAccessible(true); - methodGetParentNoClientCode = componentClass.getDeclaredMethod("getParent_NoClientCode", (Class[]) null); - methodGetParentNoClientCode.setAccessible(true); - methodGetFontNoClientCode = componentClass.getDeclaredMethod("getFont_NoClientCode", (Class[]) null); - methodGetFontNoClientCode.setAccessible(true); - Class[] argTypes = { AWTEvent.class }; - methodProcessEvent = componentClass.getDeclaredMethod("processEvent",argTypes); - methodProcessEvent.setAccessible(true); - Class[] argTypesForMethodEnableEvents = { Long.TYPE }; - methodEnableEvents = componentClass.getDeclaredMethod("enableEvents",argTypesForMethodEnableEvents); - methodEnableEvents.setAccessible(true); - - fieldParent = componentClass.getDeclaredField("parent"); - fieldParent.setAccessible(true); - fieldPacked = componentClass.getDeclaredField("isPacked"); - fieldPacked.setAccessible(true); - fieldIgnoreRepaint = componentClass.getDeclaredField("ignoreRepaint"); - fieldIgnoreRepaint.setAccessible(true); - - fieldPeer = componentClass.getDeclaredField("peer"); - fieldPeer.setAccessible(true); - - fieldVisible = componentClass.getDeclaredField("visible"); - fieldVisible.setAccessible(true); - - methodIsEnabledImpl = componentClass.getDeclaredMethod("isEnabledImpl", (Class[]) null); - methodIsEnabledImpl.setAccessible(true); - - methodGetCursorNoClientCode = componentClass.getDeclaredMethod("getCursor_NoClientCode", (Class[]) null); - methodGetCursorNoClientCode.setAccessible(true); - - methodLocationNoClientCode = componentClass.getDeclaredMethod("location_NoClientCode", (Class[]) null); - methodLocationNoClientCode.setAccessible(true); - } - catch (NoSuchFieldException e) { - log.fine("Unable to initialize ComponentAccessor", e); - } - catch (ClassNotFoundException e) { - log.fine("Unable to initialize ComponentAccessor", e); - } - catch (NoSuchMethodException e) { - log.fine("Unable to initialize ComponentAccessor", e); - } - // to please javac - return null; - } - }); - } - - public static void setX(Component c, int x) - { - try { - fieldX.setInt(c,x); - } - catch (IllegalAccessException e) - { - log.fine("Unable to access the Component object", e); - } - } - - public static void setY(Component c, int y) - { - try { - fieldY.setInt(c,y); - } - catch (IllegalAccessException e) - { - log.fine("Unable to access the Component object", e); - } - } - - public static void setWidth(Component c, int width) - { - try { - fieldWidth.setInt(c,width); - } - catch (IllegalAccessException e) - { - log.fine("Unable to access the Component object", e); - } - } - - public static void setHeight(Component c, int height) - { - try { - fieldHeight.setInt(c,height); - } - catch (IllegalAccessException e) - { - log.fine("Unable to access the Component object", e); - } - } - - public static void setBounds(Component c, int x, int y, int width, int height) - { - try { - fieldX.setInt(c,x); - fieldY.setInt(c,y); - fieldWidth.setInt(c,width); - fieldHeight.setInt(c,height); - } - catch (IllegalAccessException e) - { - log.fine("Unable to access the Component object", e); - } - } - - public static int getX(Component c) { - try { - return fieldX.getInt(c); - } - catch (IllegalAccessException e) - { - log.fine("Unable to access the Component object", e); - } - return 0; - } - - public static int getY(Component c) { - try { - return fieldY.getInt(c); - } - catch (IllegalAccessException e) - { - log.fine("Unable to access the Component object", e); - } - return 0; - } - - public static int getWidth(Component c) { - try { - return fieldWidth.getInt(c); - } - catch (IllegalAccessException e) - { - log.fine("Unable to access the Component object", e); - } - return 0; - } - - public static int getHeight(Component c) { - try { - return fieldHeight.getInt(c); - } - catch (IllegalAccessException e) - { - log.fine("Unable to access the Component object", e); - } - return 0; - } - - public static boolean getIsPacked(Component c) { - try { - return fieldPacked.getBoolean(c); - } - catch (IllegalAccessException e) - { - log.fine("Unable to access the Component object", e); - } - return false; - } - - public static Container getParent_NoClientCode(Component c) { - Container parent=null; - - try { - parent = (Container) methodGetParentNoClientCode.invoke(c, (Object[]) null); - } - catch (IllegalAccessException e) - { - log.fine("Unable to access the Component object", e); - } - catch (InvocationTargetException e) { - log.fine("Unable to invoke on the Component object", e); - } - - return parent; - } - - public static Font getFont_NoClientCode(Component c) { - Font font=null; - - try { - font = (Font) methodGetFontNoClientCode.invoke(c, (Object[]) null); - } - catch (IllegalAccessException e) - { - log.fine("Unable to access the Component object", e); - } - catch (InvocationTargetException e) { - log.fine("Unable to invoke on the Component object", e); - } - - return font; - } - - public static void processEvent(Component c, AWTEvent event) { - Font font=null; - - try { - Object[] args = new Object[1]; - args[0] = event; - methodProcessEvent.invoke(c,args); - } - catch (IllegalAccessException e) - { - log.fine("Unable to access the Component object", e); - } - catch (InvocationTargetException e) { - log.fine("Unable to invoke on the Component object", e); - } - } - - public static void enableEvents(Component c, long event_mask) { - try { - Object[] args = new Object[1]; - args[0] = Long.valueOf(event_mask); - methodEnableEvents.invoke(c,args); - } - catch (IllegalAccessException e) - { - log.fine("Unable to access the Component object", e); - } - catch (InvocationTargetException e) { - log.fine("Unable to invoke on the Component object", e); - } - } - - public static void setParent(Component c, Container parent) - { - try { - fieldParent.set(c,parent); - } - catch (IllegalAccessException e) - { - log.fine("Unable to access the Component object", e); - } - } - - public static Color getForeground(Component c) - { - Color color = null; - try { - color = (Color) fieldForeground.get(c); - } - catch (IllegalAccessException e) - { - log.fine("Unable to access the Component object", e); - } - return color; - } - - public static Color getBackground(Component c) - { - Color color = null; - try { - color = (Color) fieldBackground.get(c); - } - catch (IllegalAccessException e) - { - log.fine("Unable to access the Component object", e); - } - return color; - } - - public static void setBackground(Component c, Color color) { - try { - fieldBackground.set(c, color); - } - catch (IllegalAccessException e) - { - log.fine("Unable to access the Component object", e); - } - } - - public static Font getFont(Component c) - { - Font f = null; - try { - f = (Font) fieldFont.get(c); - } - catch (IllegalAccessException e) - { - log.fine("Unable to access the Component object", e); - } - return f; - } - - public static ComponentPeer getPeer(Component c) { - ComponentPeer peer = null; - try { - peer = (ComponentPeer)fieldPeer.get(c); - } - catch (IllegalAccessException e) - { - log.fine("Unable to access the Component object", e); - } - return peer; - } - - public static void setPeer(Component c, ComponentPeer peer) { - try { - fieldPeer.set(c, peer); - } catch (IllegalAccessException e) - { - log.fine("Unable to access the Component object", e); - } - } - - public static boolean getIgnoreRepaint(Component comp) { - try { - return fieldIgnoreRepaint.getBoolean(comp); - } - catch (IllegalAccessException e) { - log.fine("Unable to access the Component object", e); - } - - return false; - } - - public static boolean getVisible(Component c) { - try { - return fieldVisible.getBoolean(c); - } - catch (IllegalAccessException e) - { - log.fine("Unable to access the Component object", e); - } - return false; - } - - public static boolean isEnabledImpl(Component c) { - boolean enabled = true; - try { - enabled = (Boolean) methodIsEnabledImpl.invoke(c, (Object[]) null); - } - catch (IllegalAccessException e) - { - log.fine("Unable to access the Component object", e); - } - catch (InvocationTargetException e) { - log.fine("Unable to invoke on the Component object", e); - } - return enabled; - } - - public static Cursor getCursor_NoClientCode(Component c) { - Cursor cursor = null; - - try { - cursor = (Cursor) methodGetCursorNoClientCode.invoke(c, (Object[]) null); - } - catch (IllegalAccessException e) - { - log.fine("Unable to access the Component object", e); - } - catch (InvocationTargetException e) { - log.fine("Unable to invoke on the Component object", e); - } - - return cursor; - } - - public static Point getLocation_NoClientCode(Component c) { - Point loc = null; - - try { - loc = (Point) methodLocationNoClientCode.invoke(c, (Object[]) null); - } - catch (IllegalAccessException e) - { - log.fine("Unable to access the Component object", e); - } - catch (InvocationTargetException e) { - log.fine("Unable to invoke on the Component object", e); - } - - return loc; - } - -} diff -r feacdd1c5df3 -r 1411f4ebf52e jdk/src/share/classes/sun/awt/GlobalCursorManager.java --- a/jdk/src/share/classes/sun/awt/GlobalCursorManager.java Thu Dec 10 09:43:48 2009 -0800 +++ b/jdk/src/share/classes/sun/awt/GlobalCursorManager.java Thu Dec 10 09:46:13 2009 -0800 @@ -183,7 +183,7 @@ } if (comp instanceof Window) { - p = ComponentAccessor.getLocation_NoClientCode(comp); + p = AWTAccessor.getComponentAccessor().getLocation(comp); } else if (comp instanceof Container) { p = getLocationOnScreen(comp); } @@ -202,7 +202,7 @@ } } - setCursor(comp, ComponentAccessor.getCursor_NoClientCode(comp), useCache); + setCursor(comp, AWTAccessor.getComponentAccessor().getCursor(comp), useCache); } catch (IllegalComponentStateException e) { // Shouldn't happen, but if it does, abort. diff -r feacdd1c5df3 -r 1411f4ebf52e jdk/src/share/classes/sun/awt/SunToolkit.java --- a/jdk/src/share/classes/sun/awt/SunToolkit.java Thu Dec 10 09:43:48 2009 -0800 +++ b/jdk/src/share/classes/sun/awt/SunToolkit.java Thu Dec 10 09:46:13 2009 -0800 @@ -722,13 +722,7 @@ EventQueue eq = (EventQueue)appContext.get(AppContext.EVENT_QUEUE_KEY); AWTAccessor.EventQueueAccessor accessor = AWTAccessor.getEventQueueAccessor(); - EventQueue next = accessor.getNextQueue(eq); - while (next != null) { - eq = next; - next = accessor.getNextQueue(eq); - } - - return (Thread.currentThread() == accessor.getDispatchThread(eq)); + return accessor.isDispatchThreadImpl(eq); } public Dimension getScreenSize() { @@ -806,17 +800,9 @@ } - /** - * Makes the window OverrideRedirect, on X11 platforms. See - * ICCCM specification for more details about OverrideRedirect - * windows. Implemented in XToolkit, no-op in WToolkit. - */ - public void setOverrideRedirect(Window target) { - } + static final SoftCache imgCache = new SoftCache(); - static SoftCache imgCache = new SoftCache(); - - static synchronized Image getImageFromHash(Toolkit tk, URL url) { + static Image getImageFromHash(Toolkit tk, URL url) { SecurityManager sm = System.getSecurityManager(); if (sm != null) { try { @@ -844,32 +830,36 @@ sm.checkConnect(url.getHost(), url.getPort()); } } - Image img = (Image)imgCache.get(url); - if (img == null) { - try { - img = tk.createImage(new URLImageSource(url)); - imgCache.put(url, img); - } catch (Exception e) { + synchronized (imgCache) { + Image img = (Image)imgCache.get(url); + if (img == null) { + try { + img = tk.createImage(new URLImageSource(url)); + imgCache.put(url, img); + } catch (Exception e) { + } } + return img; } - return img; } - static synchronized Image getImageFromHash(Toolkit tk, + static Image getImageFromHash(Toolkit tk, String filename) { SecurityManager security = System.getSecurityManager(); if (security != null) { security.checkRead(filename); } - Image img = (Image)imgCache.get(filename); - if (img == null) { - try { - img = tk.createImage(new FileImageSource(filename)); - imgCache.put(filename, img); - } catch (Exception e) { + synchronized (imgCache) { + Image img = (Image)imgCache.get(filename); + if (img == null) { + try { + img = tk.createImage(new FileImageSource(filename)); + imgCache.put(filename, img); + } catch (Exception e) { + } } + return img; } - return img; } public Image getImage(String filename) { @@ -1129,6 +1119,18 @@ } /** + * Gives native peers the ability to query the closest HW component. + * If the given component is heavyweight, then it returns this. Otherwise, + * it goes one level up in the hierarchy and tests next component. + */ + public static Component getHeavyweightComponent(Component c) { + while (c != null && AWTAccessor.getComponentAccessor().isLightweight(c)) { + c = AWTAccessor.getComponentAccessor().getParent(c); + } + return c; + } + + /** * Returns a new input method window, with behavior as specified in * {@link java.awt.im.spi.InputMethodContext#createInputMethodWindow}. * If the inputContext is not null, the window should return it from its diff -r feacdd1c5df3 -r 1411f4ebf52e jdk/src/share/classes/sun/awt/WindowAccessor.java --- a/jdk/src/share/classes/sun/awt/WindowAccessor.java Thu Dec 10 09:43:48 2009 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,96 +0,0 @@ -/* - * Copyright 2007 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Sun designates this - * particular file as subject to the "Classpath" exception as provided - * by Sun in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, - * CA 95054 USA or visit www.sun.com if you need additional information or - * have any questions. - */ - -package sun.awt; - -import java.awt.Window; - -import java.lang.reflect.Field; - -import sun.util.logging.PlatformLogger; - -import java.security.AccessController; -import java.security.PrivilegedAction; - -public class WindowAccessor { - - private static Class windowClass; - private static Field fieldIsAutoRequestFocus; - private static Field fieldIsTrayIconWindow; - - private static final PlatformLogger log = PlatformLogger.getLogger("sun.awt.WindowAccessor"); - - private WindowAccessor() { - } - - static { - AccessController.doPrivileged( new PrivilegedAction() { - public Object run() { - try { - windowClass = Class.forName("java.awt.Window"); - fieldIsAutoRequestFocus = windowClass.getDeclaredField("autoRequestFocus"); - fieldIsAutoRequestFocus.setAccessible(true); - fieldIsTrayIconWindow = windowClass.getDeclaredField("isTrayIconWindow"); - fieldIsTrayIconWindow.setAccessible(true); - - } catch (NoSuchFieldException e) { - log.fine("Unable to initialize WindowAccessor: ", e); - } catch (ClassNotFoundException e) { - log.fine("Unable to initialize WindowAccessor: ", e); - } - return null; - } - }); - } - - public static boolean isAutoRequestFocus(Window w) { - try { - return fieldIsAutoRequestFocus.getBoolean(w); - - } catch (IllegalAccessException e) { - log.fine("Unable to access the Window object", e); - } - return true; - } - - public static boolean isTrayIconWindow(Window w) { - try { - return fieldIsTrayIconWindow.getBoolean(w); - - } catch (IllegalAccessException e) { - log.fine("Unable to access the Window object", e); - } - return false; - } - - public static void setTrayIconWindow(Window w, boolean isTrayIconWindow) { - try { - fieldIsTrayIconWindow.set(w, isTrayIconWindow); - - } catch (IllegalAccessException e) { - log.fine("Unable to access the Window object", e); - } - } -} diff -r feacdd1c5df3 -r 1411f4ebf52e jdk/src/share/classes/sun/awt/datatransfer/DataTransferer.java --- a/jdk/src/share/classes/sun/awt/datatransfer/DataTransferer.java Thu Dec 10 09:43:48 2009 -0800 +++ b/jdk/src/share/classes/sun/awt/datatransfer/DataTransferer.java Thu Dec 10 09:46:13 2009 -0800 @@ -51,6 +51,9 @@ import java.io.SequenceInputStream; import java.io.StringReader; +import java.net.URI; +import java.net.URISyntaxException; + import java.nio.ByteBuffer; import java.nio.CharBuffer; import java.nio.charset.Charset; @@ -626,6 +629,14 @@ public abstract boolean isImageFormat(long format); /** + * Determines whether the format is a URI list we can convert to + * a DataFlavor.javaFileListFlavor. + */ + protected boolean isURIListFormat(long format) { + return false; + } + + /** * Returns a Map whose keys are all of the possible formats into which the * Transferable's transfer data flavors can be translated. The value of * each key is the DataFlavor in which the Transferable's data should be @@ -1297,45 +1308,53 @@ if (!DataFlavor.javaFileListFlavor.equals(flavor)) { throw new IOException("data translation failed"); } + final List list = (List)obj; - final ArrayList fileList = new ArrayList(); - final ProtectionDomain userProtectionDomain = getUserProtectionDomain(contents); - int nFiles = 0; - for (int i = 0; i < list.size(); i++) { - Object o = list.get(i); - if (o instanceof File || o instanceof String) { - nFiles++; + final ArrayList fileList = castToFiles(list, userProtectionDomain); + + bos = convertFileListToBytes(fileList); + + + // Target data is a URI list. Source data must be a + // java.util.List which contains java.io.File or String instances. + } else if (isURIListFormat(format)) { + if (!DataFlavor.javaFileListFlavor.equals(flavor)) { + throw new IOException("data translation failed"); + } + String nat = getNativeForFormat(format); + String targetCharset = null; + if (nat != null) { + try { + targetCharset = new DataFlavor(nat).getParameter("charset"); + } catch (ClassNotFoundException cnfe) { + throw new IOException(cnfe); } } - - try { - AccessController.doPrivileged(new PrivilegedExceptionAction() { - public Object run() throws IOException { - for (Object fileObject : list) - { - File file = castToFile(fileObject); - if (null == System.getSecurityManager() || - !(isFileInWebstartedCache(file) || - isForbiddenToRead(file, userProtectionDomain))) - { - fileList.add(file.getCanonicalPath()); - } - } - return null; - } - }); - } catch (PrivilegedActionException pae) { - throw new IOException(pae.getMessage()); + if (targetCharset == null) { + targetCharset = "UTF-8"; } - - for (int i = 0; i < fileList.size(); i++) - { - byte[] bytes = ((String)fileList.get(i)).getBytes(); - if (i != 0) bos.write(0); + final List list = (List)obj; + final ProtectionDomain userProtectionDomain = getUserProtectionDomain(contents); + final ArrayList fileList = castToFiles(list, userProtectionDomain); + final ArrayList uriList = new ArrayList(fileList.size()); + for (String fileObject : fileList) { + final URI uri = new File(fileObject).toURI(); + // Some implementations are fussy about the number of slashes (file:///path/to/file is best) + try { + uriList.add(new URI(uri.getScheme(), "", uri.getPath(), uri.getFragment()).toString()); + } catch (URISyntaxException uriSyntaxException) { + throw new IOException(uriSyntaxException); + } + } + + byte[] eoln = "\r\n".getBytes(targetCharset); + for (int i = 0; i < uriList.size(); i++) { + byte[] bytes = uriList.get(i).getBytes(targetCharset); bos.write(bytes, 0, bytes.length); + bos.write(eoln, 0, eoln.length); } // Source data is an InputStream. For arbitrary flavors, just grab the @@ -1385,6 +1404,8 @@ return ret; } + protected abstract ByteArrayOutputStream convertFileListToBytes(ArrayList fileList) throws IOException; + private String removeSuspectedData(DataFlavor flavor, final Transferable contents, final String str) throws IOException { @@ -1452,6 +1473,33 @@ return true; } + private ArrayList castToFiles(final List files, + final ProtectionDomain userProtectionDomain) throws IOException + { + final ArrayList fileList = new ArrayList(); + try { + AccessController.doPrivileged(new PrivilegedExceptionAction() { + public Object run() throws IOException { + for (Object fileObject : files) + { + File file = castToFile(fileObject); + if (file != null && + (null == System.getSecurityManager() || + !(isFileInWebstartedCache(file) || + isForbiddenToRead(file, userProtectionDomain)))) + { + fileList.add(file.getCanonicalPath()); + } + } + return null; + } + }); + } catch (PrivilegedActionException pae) { + throw new IOException(pae.getMessage()); + } + return fileList; + } + // It is important do not use user's successors // of File class. private File castToFile(Object fileObject) throws IOException { @@ -1460,6 +1508,8 @@ filePath = ((File)fileObject).getCanonicalPath(); } else if (fileObject instanceof String) { filePath = (String) fileObject; + } else { + return null; } return new File(filePath); } @@ -1565,6 +1615,29 @@ // Turn the list of Files into a List and return return Arrays.asList(files); + // Source data is a URI list. Convert to DataFlavor.javaFileListFlavor + // where possible. + } else if (isURIListFormat(format) && DataFlavor.javaFileListFlavor.equals(flavor)) { + try { + URI uris[] = dragQueryURIs(str, bytes, format, localeTransferable); + if (uris == null) { + return null; + } + ArrayList files = new ArrayList(); + for (URI uri : uris) { + try { + files.add(new File(uri)); + } catch (IllegalArgumentException illegalArg) { + // When converting from URIs to less generic files, + // common practice (Wine, SWT) seems to be to + // silently drop the URIs that aren't local files. + } + } + return files; + } finally { + str.close(); + } + // Target data is a String. Strip terminating NUL bytes. Decode bytes // into characters. Search-and-replace EOLN. } else if (String.class.equals(flavor.getRepresentationClass()) && @@ -1950,6 +2023,19 @@ protected abstract String[] dragQueryFile(byte[] bytes); /** + * Decodes URIs from either a byte array or a stream. + */ + protected URI[] dragQueryURIs(InputStream stream, + byte[] bytes, + long format, + Transferable localeTransferable) + throws IOException + { + throw new IOException( + new UnsupportedOperationException("not implemented on this platform")); + } + + /** * Translates either a byte array or an input stream which contain * platform-specific image data in the given format into an Image. */ diff -r feacdd1c5df3 -r 1411f4ebf52e jdk/src/solaris/classes/sun/awt/X11/InfoWindow.java --- a/jdk/src/solaris/classes/sun/awt/X11/InfoWindow.java Thu Dec 10 09:43:48 2009 -0800 +++ b/jdk/src/solaris/classes/sun/awt/X11/InfoWindow.java Thu Dec 10 09:46:13 2009 -0800 @@ -45,6 +45,7 @@ protected InfoWindow(Frame parent, Color borderColor) { super(parent); + setType(Window.Type.POPUP); container = new Container() { @Override public Insets getInsets() { diff -r feacdd1c5df3 -r 1411f4ebf52e jdk/src/solaris/classes/sun/awt/X11/XComponentPeer.java --- a/jdk/src/solaris/classes/sun/awt/X11/XComponentPeer.java Thu Dec 10 09:43:48 2009 -0800 +++ b/jdk/src/solaris/classes/sun/awt/X11/XComponentPeer.java Thu Dec 10 09:46:13 2009 -0800 @@ -212,27 +212,6 @@ return true; } - static XComponentPeer getNativeContainer(Component comp) { - if (comp == null) { - return null; - } - - synchronized(comp.getTreeLock()) { - while (comp != null && (ComponentAccessor.getPeer(comp) instanceof LightweightPeer)) { - comp = ComponentAccessor.getParent_NoClientCode(comp); - } - - if (comp != null) { - ComponentPeer peer = ComponentAccessor.getPeer(comp); - if (peer != null && peer instanceof XComponentPeer) { - return (XComponentPeer)peer; - } - } - } - - return null; - } - /************************************************* * FOCUS STUFF *************************************************/ @@ -508,13 +487,14 @@ } XWindowPeer getParentTopLevel() { - Container parent = (target instanceof Container) ? ((Container)target) : (ComponentAccessor.getParent_NoClientCode(target)); + AWTAccessor.ComponentAccessor compAccessor = AWTAccessor.getComponentAccessor(); + Container parent = (target instanceof Container) ? ((Container)target) : (compAccessor.getParent(target)); // Search for parent window while (parent != null && !(parent instanceof Window)) { - parent = ComponentAccessor.getParent_NoClientCode(parent); + parent = compAccessor.getParent(parent); } if (parent != null) { - return (XWindowPeer)ComponentAccessor.getPeer(parent); + return (XWindowPeer)compAccessor.getPeer(parent); } else { return null; } @@ -828,7 +808,7 @@ public void endLayout() { if (!paintPending && !paintArea.isEmpty() - && !ComponentAccessor.getIgnoreRepaint(target)) + && !AWTAccessor.getComponentAccessor().getIgnoreRepaint(target)) { // if not waiting for native painting repaint damaged area postEvent(new PaintEvent(target, PaintEvent.PAINT, @@ -1239,11 +1219,11 @@ // End of multi-buffering public void notifyTextComponentChange(boolean add){ - Container parent = ComponentAccessor.getParent_NoClientCode(target); + Container parent = AWTAccessor.getComponentAccessor().getParent(target); while(!(parent == null || parent instanceof java.awt.Frame || parent instanceof java.awt.Dialog)) { - parent = ComponentAccessor.getParent_NoClientCode(parent); + parent = AWTAccessor.getComponentAccessor().getParent(parent); } /* FIX ME - FIX ME need to implement InputMethods diff -r feacdd1c5df3 -r 1411f4ebf52e jdk/src/solaris/classes/sun/awt/X11/XContentWindow.java --- a/jdk/src/solaris/classes/sun/awt/X11/XContentWindow.java Thu Dec 10 09:43:48 2009 -0800 +++ b/jdk/src/solaris/classes/sun/awt/X11/XContentWindow.java Thu Dec 10 09:46:13 2009 -0800 @@ -32,7 +32,7 @@ import sun.util.logging.PlatformLogger; -import sun.awt.ComponentAccessor; +import sun.awt.AWTAccessor; /** * This class implements window which serves as content window for decorated frames. @@ -135,8 +135,7 @@ // NOTE: This method may be called by privileged threads. // DO NOT INVOKE CLIENT CODE ON THIS THREAD! public void handleResize(Rectangle bounds) { - ComponentAccessor.setWidth((Component)target, bounds.width); - ComponentAccessor.setHeight((Component)target, bounds.height); + AWTAccessor.getComponentAccessor().setSize((Component)target, bounds.width, bounds.height); postEvent(new ComponentEvent(target, ComponentEvent.COMPONENT_RESIZED)); } diff -r feacdd1c5df3 -r 1411f4ebf52e jdk/src/solaris/classes/sun/awt/X11/XDataTransferer.java --- a/jdk/src/solaris/classes/sun/awt/X11/XDataTransferer.java Thu Dec 10 09:43:48 2009 -0800 +++ b/jdk/src/solaris/classes/sun/awt/X11/XDataTransferer.java Thu Dec 10 09:46:13 2009 -0800 @@ -28,14 +28,21 @@ import java.awt.Image; import java.awt.datatransfer.DataFlavor; +import java.awt.datatransfer.Transferable; +import java.awt.datatransfer.UnsupportedFlavorException; import java.awt.image.BufferedImage; import java.awt.image.ColorModel; import java.awt.image.WritableRaster; +import java.io.BufferedReader; import java.io.InputStream; +import java.io.InputStreamReader; import java.io.IOException; +import java.net.URI; +import java.net.URISyntaxException; + import java.util.ArrayList; import java.util.Iterator; import java.util.List; @@ -48,6 +55,8 @@ import sun.awt.datatransfer.DataTransferer; import sun.awt.datatransfer.ToolkitThreadBlockedHandler; +import java.io.ByteArrayOutputStream; + /** * Platform-specific support for the data transfer subsystem. */ @@ -108,6 +117,22 @@ return super.getCharsetForTextFormat(lFormat); } + protected boolean isURIListFormat(long format) { + String nat = getNativeForFormat(format); + if (nat == null) { + return false; + } + try { + DataFlavor df = new DataFlavor(nat); + if (df.getPrimaryType().equals("text") && df.getSubType().equals("uri-list")) { + return true; + } + } catch (Exception e) { + // Not a MIME format. + } + return false; + } + public boolean isFileFormat(long format) { return format == FILE_NAME_ATOM.getAtom() || format == DT_NET_FILE_ATOM.getAtom(); @@ -170,6 +195,19 @@ } } + protected ByteArrayOutputStream convertFileListToBytes(ArrayList fileList) + throws IOException + { + ByteArrayOutputStream bos = new ByteArrayOutputStream(); + for (int i = 0; i < fileList.size(); i++) + { + byte[] bytes = fileList.get(i).getBytes(); + if (i != 0) bos.write(0); + bos.write(bytes, 0, bytes.length); + } + return bos; + } + /** * Translates either a byte array or an input stream which contain * platform-specific image data in the given format into an Image. @@ -215,6 +253,52 @@ } } + protected URI[] dragQueryURIs(InputStream stream, + byte[] bytes, + long format, + Transferable localeTransferable) + throws IOException { + + String charset = null; + if (localeTransferable != null && + isLocaleDependentTextFormat(format) && + localeTransferable.isDataFlavorSupported(javaTextEncodingFlavor)) { + try { + charset = new String( + (byte[])localeTransferable.getTransferData(javaTextEncodingFlavor), + "UTF-8" + ); + } catch (UnsupportedFlavorException cannotHappen) { + } + } else { + charset = getCharsetForTextFormat(format); + } + if (charset == null) { + // Only happens when we have a custom text type. + charset = getDefaultTextCharset(); + } + + BufferedReader reader = null; + try { + reader = new BufferedReader(new InputStreamReader(stream, charset)); + String line; + ArrayList uriList = new ArrayList(); + URI uri; + while ((line = reader.readLine()) != null) { + try { + uri = new URI(line); + } catch (URISyntaxException uriSyntaxException) { + throw new IOException(uriSyntaxException); + } + uriList.add(uri); + } + return uriList.toArray(new URI[uriList.size()]); + } finally { + if (reader != null) + reader.close(); + } + } + /** * Returns true if and only if the name of the specified format Atom * constitutes a valid MIME type with the specified primary type. diff -r feacdd1c5df3 -r 1411f4ebf52e jdk/src/solaris/classes/sun/awt/X11/XDecoratedPeer.java --- a/jdk/src/solaris/classes/sun/awt/X11/XDecoratedPeer.java Thu Dec 10 09:43:48 2009 -0800 +++ b/jdk/src/solaris/classes/sun/awt/X11/XDecoratedPeer.java Thu Dec 10 09:46:13 2009 -0800 @@ -32,7 +32,7 @@ import sun.util.logging.PlatformLogger; -import sun.awt.ComponentAccessor; +import sun.awt.AWTAccessor; import sun.awt.SunToolkit; abstract class XDecoratedPeer extends XWindowPeer { @@ -167,10 +167,11 @@ } public Graphics getGraphics() { + AWTAccessor.ComponentAccessor compAccessor = AWTAccessor.getComponentAccessor(); return getGraphics(content.surfaceData, - ComponentAccessor.getForeground(target), - ComponentAccessor.getBackground(target), - ComponentAccessor.getFont_NoClientCode(target)); + compAccessor.getForeground(target), + compAccessor.getBackground(target), + compAccessor.getFont(target)); } public void setTitle(String title) { @@ -404,8 +405,7 @@ public void handleMoved(WindowDimensions dims) { Point loc = dims.getLocation(); - ComponentAccessor.setX((Component)target, loc.x); - ComponentAccessor.setY((Component)target, loc.y); + AWTAccessor.getComponentAccessor().setLocation((Component)target, loc.x, loc.y); postEvent(new ComponentEvent(target, ComponentEvent.COMPONENT_MOVED)); } @@ -511,8 +511,8 @@ // its location changes. Point oldLocation = getLocation(); - Point newLocation = new Point(ComponentAccessor.getX((Component)target), - ComponentAccessor.getY((Component)target)); + Point newLocation = new Point(AWTAccessor.getComponentAccessor().getX((Component)target), + AWTAccessor.getComponentAccessor().getY((Component)target)); if (!newLocation.equals(oldLocation)) { handleMoved(newDimensions); @@ -710,10 +710,7 @@ updateChildrenSizes(); // Bounds of the window - Rectangle targetBounds = new Rectangle(ComponentAccessor.getX((Component)target), - ComponentAccessor.getY((Component)target), - ComponentAccessor.getWidth((Component)target), - ComponentAccessor.getHeight((Component)target)); + Rectangle targetBounds = AWTAccessor.getComponentAccessor().getBounds((Component)target); Point newLocation = targetBounds.getLocation(); if (xe.get_send_event() || runningWM == XWM.NO_WM || XWM.isNonReparentingWM()) { @@ -1042,10 +1039,11 @@ } final void dumpTarget() { - int getWidth = ComponentAccessor.getWidth((Component)target); - int getHeight = ComponentAccessor.getHeight((Component)target); - int getTargetX = ComponentAccessor.getX((Component)target); - int getTargetY = ComponentAccessor.getY((Component)target); + AWTAccessor.ComponentAccessor compAccessor = AWTAccessor.getComponentAccessor(); + int getWidth = compAccessor.getWidth((Component)target); + int getHeight = compAccessor.getHeight((Component)target); + int getTargetX = compAccessor.getX((Component)target); + int getTargetY = compAccessor.getY((Component)target); System.err.println(">>> Target: " + getTargetX + ", " + getTargetY + ", " + getWidth + ", " + getHeight); } @@ -1099,9 +1097,9 @@ return false; } + @Override boolean isOverrideRedirect() { -// return false; - return ((XToolkit)Toolkit.getDefaultToolkit()).isOverrideRedirect((Window)target); + return Window.Type.POPUP.equals(getWindowType()); } public boolean requestWindowFocus(long time, boolean timeProvided) { @@ -1208,7 +1206,7 @@ Window owner = XWindowPeer.getDecoratedOwner(actualFocusedWindow); if (owner != null && owner == target) { - setActualFocusedWindow((XWindowPeer) ComponentAccessor.getPeer(actualFocusedWindow)); + setActualFocusedWindow((XWindowPeer) AWTAccessor.getComponentAccessor().getPeer(actualFocusedWindow)); } } super.handleWindowFocusOut(oppositeWindow, serial); diff -r feacdd1c5df3 -r 1411f4ebf52e jdk/src/solaris/classes/sun/awt/X11/XDialogPeer.java --- a/jdk/src/solaris/classes/sun/awt/X11/XDialogPeer.java Thu Dec 10 09:43:48 2009 -0800 +++ b/jdk/src/solaris/classes/sun/awt/X11/XDialogPeer.java Thu Dec 10 09:46:13 2009 -0800 @@ -28,7 +28,7 @@ import java.awt.*; import java.awt.peer.*; import java.awt.event.*; -import sun.awt.ComponentAccessor; +import sun.awt.AWTAccessor; import sun.awt.*; @@ -117,7 +117,7 @@ try { javaToplevels = XWindowPeer.collectJavaToplevels(); for (Window w : toBlock) { - XWindowPeer wp = (XWindowPeer)ComponentAccessor.getPeer(w); + XWindowPeer wp = (XWindowPeer)AWTAccessor.getComponentAccessor().getPeer(w); if (wp != null) { wp.setModalBlocked((Dialog)target, true, javaToplevels); } @@ -139,7 +139,7 @@ XWindowPeer focusedWindowPeer = null; if (focusedWindow != null) { - focusedWindowPeer = (XWindowPeer)ComponentAccessor.getPeer(focusedWindow); + focusedWindowPeer = (XWindowPeer)AWTAccessor.getComponentAccessor().getPeer(focusedWindow); } else { /* * For the case when a potential blocked window is not yet focused diff -r feacdd1c5df3 -r 1411f4ebf52e jdk/src/solaris/classes/sun/awt/X11/XDragSourceContextPeer.java --- a/jdk/src/solaris/classes/sun/awt/X11/XDragSourceContextPeer.java Thu Dec 10 09:43:48 2009 -0800 +++ b/jdk/src/solaris/classes/sun/awt/X11/XDragSourceContextPeer.java Thu Dec 10 09:46:13 2009 -0800 @@ -39,11 +39,10 @@ import sun.util.logging.PlatformLogger; -import sun.awt.ComponentAccessor; - import sun.awt.dnd.SunDragSourceContextPeer; import sun.awt.dnd.SunDropTargetContextPeer; import sun.awt.SunToolkit; +import sun.awt.AWTAccessor; /** * The XDragSourceContextPeer class is the class responsible for handling @@ -117,7 +116,7 @@ XWindowPeer wpeer = null; for (c = component; c != null && !(c instanceof Window); - c = ComponentAccessor.getParent_NoClientCode(c)); + c = AWTAccessor.getComponentAccessor().getParent(c)); if (c instanceof Window) { wpeer = (XWindowPeer)c.getPeer(); diff -r feacdd1c5df3 -r 1411f4ebf52e jdk/src/solaris/classes/sun/awt/X11/XEmbedChildProxy.java --- a/jdk/src/solaris/classes/sun/awt/X11/XEmbedChildProxy.java Thu Dec 10 09:43:48 2009 -0800 +++ b/jdk/src/solaris/classes/sun/awt/X11/XEmbedChildProxy.java Thu Dec 10 09:46:13 2009 -0800 @@ -27,7 +27,7 @@ import java.awt.Component; import java.awt.Toolkit; -import sun.awt.ComponentAccessor; +import sun.awt.AWTAccessor; public class XEmbedChildProxy extends Component { long handle; @@ -39,8 +39,9 @@ public void addNotify() { synchronized(getTreeLock()) { - if (ComponentAccessor.getPeer(this) == null) { - ComponentAccessor.setPeer(this, ((XToolkit)Toolkit.getDefaultToolkit()).createEmbedProxy(this)); + if (AWTAccessor.getComponentAccessor().getPeer(this) == null) { + AWTAccessor.getComponentAccessor(). + setPeer(this,((XToolkit)Toolkit.getDefaultToolkit()).createEmbedProxy(this)); } super.addNotify(); } diff -r feacdd1c5df3 -r 1411f4ebf52e jdk/src/solaris/classes/sun/awt/X11/XEmbedClientHelper.java --- a/jdk/src/solaris/classes/sun/awt/X11/XEmbedClientHelper.java Thu Dec 10 09:43:48 2009 -0800 +++ b/jdk/src/solaris/classes/sun/awt/X11/XEmbedClientHelper.java Thu Dec 10 09:46:13 2009 -0800 @@ -133,7 +133,7 @@ } void handleFocusIn(int detail) { if (embedded.focusAllowedFor()) { - embedded.handleWindowFocusInSync(0); + embedded.handleWindowFocusIn(0); } switch(detail) { case XEMBED_FOCUS_CURRENT: @@ -205,7 +205,7 @@ // embedded is an active window before sending WINDOW_LOST_FOCUS // to shared code if (XKeyboardFocusManagerPeer.getCurrentNativeFocusedWindow() == embedded.target) { - embedded.handleWindowFocusOutSync(null, 0); + embedded.handleWindowFocusOut(null, 0); } } diff -r feacdd1c5df3 -r 1411f4ebf52e jdk/src/solaris/classes/sun/awt/X11/XEmbedHelper.java --- a/jdk/src/solaris/classes/sun/awt/X11/XEmbedHelper.java Thu Dec 10 09:43:48 2009 -0800 +++ b/jdk/src/solaris/classes/sun/awt/X11/XEmbedHelper.java Thu Dec 10 09:46:13 2009 -0800 @@ -216,7 +216,12 @@ XToolkit.awtLock(); try { - keycode = XWindow.getAWTKeyCodeForKeySym((int)keysym); + XKeysym.Keysym2JavaKeycode kc = XKeysym.getJavaKeycode( keysym ); + if(kc == null) { + keycode = java.awt.event.KeyEvent.VK_UNDEFINED; + }else{ + keycode = kc.getJavaKeycode(); + } } finally { XToolkit.awtUnlock(); } diff -r feacdd1c5df3 -r 1411f4ebf52e jdk/src/solaris/classes/sun/awt/X11/XGlobalCursorManager.java --- a/jdk/src/solaris/classes/sun/awt/X11/XGlobalCursorManager.java Thu Dec 10 09:43:48 2009 -0800 +++ b/jdk/src/solaris/classes/sun/awt/X11/XGlobalCursorManager.java Thu Dec 10 09:46:13 2009 -0800 @@ -31,7 +31,7 @@ import java.lang.ref.WeakReference; import java.lang.reflect.Field; import java.lang.reflect.Method; -import sun.awt.ComponentAccessor; +import sun.awt.AWTAccessor; import sun.awt.GlobalCursorManager; import sun.awt.SunToolkit; @@ -94,11 +94,11 @@ nc = nativeContainer.get(); } } else { - nc = getNativeContainer(comp); + nc = SunToolkit.getHeavyweightComponent(comp); } if (nc != null) { - ComponentPeer nc_peer = ComponentAccessor.getPeer(nc); + ComponentPeer nc_peer = AWTAccessor.getComponentAccessor().getPeer(nc); if (nc_peer instanceof XComponentPeer) { synchronized (this) { nativeContainer = new WeakReference(nc); @@ -133,13 +133,6 @@ updateGrabbedCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR)); } - private Component getNativeContainer(Component comp) { - while (comp != null && ComponentAccessor.getPeer(comp) instanceof LightweightPeer) { - comp = ComponentAccessor.getParent_NoClientCode(comp); - } - return comp; - } - protected void getCursorPos(Point p) { if (!((XToolkit)Toolkit.getDefaultToolkit()).getLastCursorPos(p)) { @@ -186,27 +179,29 @@ } private Cursor getCapableCursor(Component comp) { + AWTAccessor.ComponentAccessor compAccessor = AWTAccessor.getComponentAccessor(); + Component c = comp; while ((c != null) && !(c instanceof Window) - && ComponentAccessor.isEnabledImpl(c) - && ComponentAccessor.getVisible(c) - && ComponentAccessor.getPeer(c) != null) + && compAccessor.isEnabled(c) + && compAccessor.isVisible(c) + && compAccessor.isDisplayable(c)) { - c = ComponentAccessor.getParent_NoClientCode(c); + c = compAccessor.getParent(c); } if (c instanceof Window) { - return (ComponentAccessor.isEnabledImpl(c) - && ComponentAccessor.getVisible(c) - && (ComponentAccessor.getPeer(c) != null) - && ComponentAccessor.isEnabledImpl(comp)) + return (compAccessor.isEnabled(c) + && compAccessor.isVisible(c) + && compAccessor.isDisplayable(c) + && compAccessor.isEnabled(comp)) ? - ComponentAccessor.getCursor_NoClientCode(comp) + compAccessor.getCursor(comp) : Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR); } else if (c == null) { return null; } - return getCapableCursor(ComponentAccessor.getParent_NoClientCode(c)); + return getCapableCursor(compAccessor.getParent(c)); } /* This methods needs to be called from within XToolkit.awtLock / XToolkit.awtUnlock section. */ diff -r feacdd1c5df3 -r 1411f4ebf52e jdk/src/solaris/classes/sun/awt/X11/XKeysym.java --- a/jdk/src/solaris/classes/sun/awt/X11/XKeysym.java Thu Dec 10 09:43:48 2009 -0800 +++ b/jdk/src/solaris/classes/sun/awt/X11/XKeysym.java Thu Dec 10 09:46:13 2009 -0800 @@ -69,6 +69,8 @@ static Hashtable javaKeycode2KeysymHash = new Hashtable(); static long keysym_lowercase = unsafe.allocateMemory(Native.getLongSize()); static long keysym_uppercase = unsafe.allocateMemory(Native.getLongSize()); + static Keysym2JavaKeycode kanaLock = new Keysym2JavaKeycode(java.awt.event.KeyEvent.VK_KANA_LOCK, + java.awt.event.KeyEvent.KEY_LOCATION_STANDARD); private static PlatformLogger keyEventLog = PlatformLogger.getLogger("sun.awt.X11.kye.XKeysym"); public static char convertKeysym( long ks, int state ) { @@ -214,12 +216,35 @@ } return keysym; } + + /** + Return java.awt.KeyEvent constant meaning (Java) keycode, derived from X keysym. + Some keysyms maps to more than one keycode, these would require extra processing. + */ + static Keysym2JavaKeycode getJavaKeycode( long keysym ) { + if(keysym == XKeySymConstants.XK_Mode_switch){ + /* XK_Mode_switch on solaris maps either to VK_ALT_GRAPH (default) or VK_KANA_LOCK */ + if( XToolkit.isKanaKeyboard() ) { + return kanaLock; + } + }else if(keysym == XKeySymConstants.XK_L1){ + /* if it is Sun keyboard, trick hash to return VK_STOP else VK_F11 (default) */ + if( XToolkit.isSunKeyboard() ) { + keysym = XKeySymConstants.SunXK_Stop; + } + }else if(keysym == XKeySymConstants.XK_L2) { + /* if it is Sun keyboard, trick hash to return VK_AGAIN else VK_F12 (default) */ + if( XToolkit.isSunKeyboard() ) { + keysym = XKeySymConstants.SunXK_Again; + } + } + + return keysym2JavaKeycodeHash.get( keysym ); + } /** Return java.awt.KeyEvent constant meaning (Java) keycode, derived from X Window KeyEvent. Algorithm is, extract via XKeycodeToKeysym a proper keysym according to Xlib spec rules and err exceptions, then search a java keycode in a table. - Some keysyms maps to more than one keycode, these would require extra processing. If someone - points me to such a keysym. */ static Keysym2JavaKeycode getJavaKeycode( XKeyEvent ev ) { // get from keysym2JavaKeycodeHash. @@ -234,7 +259,7 @@ keysym = xkeycode2keysym(ev, ndx); } - Keysym2JavaKeycode jkc = keysym2JavaKeycodeHash.get( keysym ); + Keysym2JavaKeycode jkc = getJavaKeycode( keysym ); return jkc; } static int getJavaKeycodeOnly( XKeyEvent ev ) { @@ -259,7 +284,7 @@ ndx = 0; keysym = xkeycode2keysym_noxkb(ev, ndx); } - Keysym2JavaKeycode jkc = keysym2JavaKeycodeHash.get( keysym ); + Keysym2JavaKeycode jkc = getJavaKeycode( keysym ); return jkc == null ? java.awt.event.KeyEvent.VK_UNDEFINED : jkc.getJavaKeycode(); } static long javaKeycode2Keysym( int jkey ) { diff -r feacdd1c5df3 -r 1411f4ebf52e jdk/src/solaris/classes/sun/awt/X11/XNETProtocol.java --- a/jdk/src/solaris/classes/sun/awt/X11/XNETProtocol.java Thu Dec 10 09:43:48 2009 -0800 +++ b/jdk/src/solaris/classes/sun/awt/X11/XNETProtocol.java Thu Dec 10 09:46:13 2009 -0800 @@ -252,8 +252,11 @@ XAtom XA_NET_WM_STATE_SKIP_TASKBAR = XAtom.get("_NET_WM_STATE_SKIP_TASKBAR"); XAtom XA_NET_WM_STATE_SKIP_PAGER = XAtom.get("_NET_WM_STATE_SKIP_PAGER"); - XAtom XA_NET_WM_WINDOW_TYPE = XAtom.get("_NET_WM_WINDOW_TYPE"); - XAtom XA_NET_WM_WINDOW_TYPE_DIALOG = XAtom.get("_NET_WM_WINDOW_TYPE_DIALOG"); + public final XAtom XA_NET_WM_WINDOW_TYPE = XAtom.get("_NET_WM_WINDOW_TYPE"); + public final XAtom XA_NET_WM_WINDOW_TYPE_NORMAL = XAtom.get("_NET_WM_WINDOW_TYPE_NORMAL"); + public final XAtom XA_NET_WM_WINDOW_TYPE_DIALOG = XAtom.get("_NET_WM_WINDOW_TYPE_DIALOG"); + public final XAtom XA_NET_WM_WINDOW_TYPE_UTILITY = XAtom.get("_NET_WM_WINDOW_TYPE_UTILITY"); + public final XAtom XA_NET_WM_WINDOW_TYPE_POPUP_MENU = XAtom.get("_NET_WM_WINDOW_TYPE_POPUP_MENU"); XAtom XA_NET_WM_WINDOW_OPACITY = XAtom.get("_NET_WM_WINDOW_OPACITY"); diff -r feacdd1c5df3 -r 1411f4ebf52e jdk/src/solaris/classes/sun/awt/X11/XTextAreaPeer.java --- a/jdk/src/solaris/classes/sun/awt/X11/XTextAreaPeer.java Thu Dec 10 09:43:48 2009 -0800 +++ b/jdk/src/solaris/classes/sun/awt/X11/XTextAreaPeer.java Thu Dec 10 09:46:13 2009 -0800 @@ -60,7 +60,7 @@ import javax.swing.plaf.BorderUIResource; import java.awt.im.InputMethodRequests; import sun.awt.CausedFocusEvent; -import sun.awt.ComponentAccessor; +import sun.awt.AWTAccessor; class XTextAreaPeer extends XComponentPeer implements TextAreaPeer { @@ -119,13 +119,14 @@ textPane.setVisible(true); textPane.validate(); - foreground = ComponentAccessor.getForeground(target); + AWTAccessor.ComponentAccessor compAccessor = AWTAccessor.getComponentAccessor(); + foreground = compAccessor.getForeground(target); if (foreground == null) { foreground = SystemColor.textText; } setForeground(foreground); - background = ComponentAccessor.getBackground(target); + background = compAccessor.getBackground(target); if (background == null) { if (target.isEditable()) background = SystemColor.text; else background = SystemColor.control; @@ -134,8 +135,8 @@ if (!target.isBackgroundSet()) { // This is a way to set the background color of the TextArea - // without calling setBackground - go through reflection - ComponentAccessor.setBackground(target, background); + // without calling setBackground - go through accessor + compAccessor.setBackground(target, background); } if (!target.isForegroundSet()) { target.setForeground(SystemColor.textText); @@ -311,13 +312,13 @@ } void handleJavaKeyEvent(KeyEvent e) { - ComponentAccessor.processEvent(jtext,e); + AWTAccessor.getComponentAccessor().processEvent(jtext,e); } public boolean handlesWheelScrolling() { return true; } void handleJavaMouseWheelEvent(MouseWheelEvent e) { - ComponentAccessor.processEvent(textPane,e); + AWTAccessor.getComponentAccessor().processEvent(textPane,e); } public void handleJavaMouseEvent( MouseEvent e ) { @@ -1111,7 +1112,7 @@ this.xwin = xwin; setDoubleBuffered(true); jt.addFocusListener(this); - ComponentAccessor.setParent(this,parent); + AWTAccessor.getComponentAccessor().setParent(this,parent); setViewportBorder(new BevelBorder(false,SystemColor.controlDkShadow,SystemColor.controlLtHighlight) ); this.jtext = jt; setFocusable(false); @@ -1308,7 +1309,7 @@ c = current.getButton(); p = toLocalSpace( c, p ); } - ComponentAccessor.processEvent( c, newMouseEvent( c, p, event ) ); + AWTAccessor.getComponentAccessor().processEvent( c, newMouseEvent( c, p, event ) ); break; } } diff -r feacdd1c5df3 -r 1411f4ebf52e jdk/src/solaris/classes/sun/awt/X11/XTextFieldPeer.java --- a/jdk/src/solaris/classes/sun/awt/X11/XTextFieldPeer.java Thu Dec 10 09:43:48 2009 -0800 +++ b/jdk/src/solaris/classes/sun/awt/X11/XTextFieldPeer.java Thu Dec 10 09:46:13 2009 -0800 @@ -55,7 +55,7 @@ import sun.util.logging.PlatformLogger; import sun.awt.CausedFocusEvent; -import sun.awt.ComponentAccessor; +import sun.awt.AWTAccessor; public class XTextFieldPeer extends XComponentPeer implements TextFieldPeer { private static final PlatformLogger log = PlatformLogger.getLogger("sun.awt.X11.XTextField"); @@ -115,13 +115,14 @@ setBounds(x, y, width, height, SET_BOUNDS); - foreground = ComponentAccessor.getForeground(target); + AWTAccessor.ComponentAccessor compAccessor = AWTAccessor.getComponentAccessor(); + foreground = compAccessor.getForeground(target); if (foreground == null) foreground = SystemColor.textText; setForeground(foreground); - background = ComponentAccessor.getBackground(target); + background = compAccessor.getBackground(target); if (background == null) { if (((TextField)target).isEditable()) background = SystemColor.text; else background = SystemColor.control; @@ -130,8 +131,8 @@ if (!target.isBackgroundSet()) { // This is a way to set the background color of the TextArea - // without calling setBackground - go through reflection - ComponentAccessor.setBackground(target, background); + // without calling setBackground - go through accessor + compAccessor.setBackground(target, background); } if (!target.isForegroundSet()) { target.setForeground(SystemColor.textText); @@ -392,7 +393,7 @@ } void handleJavaKeyEvent(KeyEvent e) { - ComponentAccessor.processEvent(xtext,e); + AWTAccessor.getComponentAccessor().processEvent(xtext,e); } @@ -620,7 +621,7 @@ this.peer = peer; setDoubleBuffered(true); setFocusable(false); - ComponentAccessor.setParent(this,parent); + AWTAccessor.getComponentAccessor().setParent(this,parent); setBackground(peer.getPeerBackground()); setForeground(peer.getPeerForeground()); setFont(peer.getPeerFont()); diff -r feacdd1c5df3 -r 1411f4ebf52e jdk/src/solaris/classes/sun/awt/X11/XToolkit.java --- a/jdk/src/solaris/classes/sun/awt/X11/XToolkit.java Thu Dec 10 09:43:48 2009 -0800 +++ b/jdk/src/solaris/classes/sun/awt/X11/XToolkit.java Thu Dec 10 09:46:13 2009 -0800 @@ -109,11 +109,6 @@ static int awt_multiclick_time; static boolean securityWarningEnabled; - // WeakSet should be used here, but there is no such class - // in JDK (at least in JDK6 and earlier versions) - private WeakHashMap overrideRedirectWindows = - new WeakHashMap(); - private static int screenWidth = -1, screenHeight = -1; // Dimensions of default screen static long awt_defaultFg; // Pixel private static XMouseInfoPeer xPeer; @@ -538,6 +533,16 @@ processGlobalMotionEvent(ev); } + if( ev.get_type() == XConstants.MappingNotify ) { + // The 'window' field in this event is unused. + // This application itself does nothing to initiate such an event + // (no calls of XChangeKeyboardMapping etc.). + // SunRay server sends this event to the application once on every + // keyboard (not just layout) change which means, quite seldom. + XlibWrapper.XRefreshKeyboardMapping(ev.pData); + resetKeyboardSniffer(); + setupModifierMap(); + } XBaseWindow.dispatchToWindow(ev); Collection dispatchers = null; @@ -631,7 +636,7 @@ Component owner = XKeyboardFocusManagerPeer.getCurrentNativeFocusOwner(); if (owner != null) { - XWindow ownerWindow = (XWindow) ComponentAccessor.getPeer(owner); + XWindow ownerWindow = (XWindow) AWTAccessor.getComponentAccessor().getPeer(owner); if (ownerWindow != null) { w = ownerWindow.getContentWindow(); } @@ -1316,19 +1321,6 @@ } } - @Override - public void setOverrideRedirect(Window target) { - synchronized (overrideRedirectWindows) { - overrideRedirectWindows.put(target, true); - } - } - - public boolean isOverrideRedirect(Window target) { - synchronized (overrideRedirectWindows) { - return overrideRedirectWindows.containsKey(target); - } - } - static void dumpPeers() { if (log.isLoggable(PlatformLogger.FINE)) { log.fine("Mapped windows:"); @@ -1457,7 +1449,7 @@ * (which is assigned to the virtual pointer) reports the maximum * capabilities of the mouse pointer (i.e. 32 physical buttons). */ - private native synchronized int getNumberOfButtonsImpl(); + private native int getNumberOfButtonsImpl(); @Override public int getNumberOfButtons(){ @@ -2130,6 +2122,11 @@ static final int XSUN_KP_BEHAVIOR = 1; static final int XORG_KP_BEHAVIOR = 2; + static final int IS_SUN_KEYBOARD = 1; + static final int IS_NONSUN_KEYBOARD = 2; + static final int IS_KANA_KEYBOARD = 1; + static final int IS_NONKANA_KEYBOARD = 2; + static int awt_IsXsunKPBehavior = 0; static boolean awt_UseXKB = false; @@ -2159,6 +2156,33 @@ awtUnlock(); } } + + static int sunOrNotKeyboard = 0; + static int kanaOrNotKeyboard = 0; + static void resetKeyboardSniffer() { + sunOrNotKeyboard = 0; + kanaOrNotKeyboard = 0; + } + static boolean isSunKeyboard() { + if( sunOrNotKeyboard == 0 ) { + if( XlibWrapper.IsSunKeyboard( getDisplay() )) { + sunOrNotKeyboard = IS_SUN_KEYBOARD; + }else{ + sunOrNotKeyboard = IS_NONSUN_KEYBOARD; + } + } + return (sunOrNotKeyboard == IS_SUN_KEYBOARD); + } + static boolean isKanaKeyboard() { + if( kanaOrNotKeyboard == 0 ) { + if( XlibWrapper.IsKanaKeyboard( getDisplay() )) { + kanaOrNotKeyboard = IS_KANA_KEYBOARD; + }else{ + kanaOrNotKeyboard = IS_NONKANA_KEYBOARD; + } + } + return (kanaOrNotKeyboard == IS_KANA_KEYBOARD); + } static boolean isXKBenabled() { awtLock(); try { diff -r feacdd1c5df3 -r 1411f4ebf52e jdk/src/solaris/classes/sun/awt/X11/XTrayIconPeer.java --- a/jdk/src/solaris/classes/sun/awt/X11/XTrayIconPeer.java Thu Dec 10 09:43:48 2009 -0800 +++ b/jdk/src/solaris/classes/sun/awt/X11/XTrayIconPeer.java Thu Dec 10 09:46:13 2009 -0800 @@ -295,7 +295,7 @@ } public static void suppressWarningString(Window w) { - WindowAccessor.setTrayIconWindow(w, true); + AWTAccessor.getWindowAccessor().setTrayIconWindow(w, true); } public void setToolTip(String tooltip) { @@ -483,12 +483,6 @@ } } - static boolean isTrayIconStuffWindow(Window w) { - return (w instanceof InfoWindow.Tooltip) || - (w instanceof InfoWindow.Balloon) || - (w instanceof XTrayIconEmbeddedFrame); - } - // *************************************** // Special embedded frame for tray icon // *************************************** diff -r feacdd1c5df3 -r 1411f4ebf52e jdk/src/solaris/classes/sun/awt/X11/XWindow.java --- a/jdk/src/solaris/classes/sun/awt/X11/XWindow.java Thu Dec 10 09:43:48 2009 -0800 +++ b/jdk/src/solaris/classes/sun/awt/X11/XWindow.java Thu Dec 10 09:46:13 2009 -0800 @@ -325,9 +325,9 @@ if (!(target instanceof Container) || win == null || win.getTarget() == null) { return false; } - Container parent = ComponentAccessor.getParent_NoClientCode(win.target); + Container parent = AWTAccessor.getComponentAccessor().getParent(win.target); while (parent != null && parent != target) { - parent = ComponentAccessor.getParent_NoClientCode(parent); + parent = AWTAccessor.getComponentAccessor().getParent(parent); } return (parent == target); } @@ -560,10 +560,11 @@ int h = xe.get_height(); Component target = (Component)getEventSource(); + AWTAccessor.ComponentAccessor compAccessor = AWTAccessor.getComponentAccessor(); - if (!ComponentAccessor.getIgnoreRepaint(target) - && ComponentAccessor.getWidth(target) != 0 - && ComponentAccessor.getHeight(target) != 0) + if (!compAccessor.getIgnoreRepaint(target) + && compAccessor.getWidth(target) != 0 + && compAccessor.getHeight(target) != 0) { handleExposeEvent(target, x, y, w, h); } @@ -950,7 +951,7 @@ XAwtState.setComponentMouseEntered(null); } } else { - ((XComponentPeer) ComponentAccessor.getPeer(target)) + ((XComponentPeer) AWTAccessor.getComponentAccessor().getPeer(target)) .pSetCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR)); } } @@ -1387,7 +1388,7 @@ Component comp = target; while (comp != null && !(comp instanceof Window)) { - comp = ComponentAccessor.getParent_NoClientCode(comp); + comp = AWTAccessor.getComponentAccessor().getParent(comp); } // applets, embedded, etc - translate directly diff -r feacdd1c5df3 -r 1411f4ebf52e jdk/src/solaris/classes/sun/awt/X11/XWindowPeer.java --- a/jdk/src/solaris/classes/sun/awt/X11/XWindowPeer.java Thu Dec 10 09:43:48 2009 -0800 +++ b/jdk/src/solaris/classes/sun/awt/X11/XWindowPeer.java Thu Dec 10 09:46:13 2009 -0800 @@ -35,18 +35,22 @@ import java.awt.peer.ComponentPeer; import java.awt.peer.WindowPeer; +import java.io.UnsupportedEncodingException; + +import java.security.AccessController; +import java.security.PrivilegedAction; + import java.util.ArrayList; import java.util.HashSet; import java.util.Iterator; import java.util.Set; import java.util.Vector; +import java.util.concurrent.atomic.AtomicBoolean; + import sun.util.logging.PlatformLogger; import sun.awt.AWTAccessor; -import sun.awt.ComponentAccessor; -import sun.awt.WindowAccessor; -import sun.awt.AWTAccessor; import sun.awt.DisplayChangedListener; import sun.awt.SunToolkit; import sun.awt.X11GraphicsDevice; @@ -90,6 +94,8 @@ private boolean mustControlStackPosition = false; // Am override-redirect not on top private XEventDispatcher rootPropertyEventDispatcher = null; + private static final AtomicBoolean isStartupNotificationRemoved = new AtomicBoolean(); + /* * Focus related flags */ @@ -97,6 +103,18 @@ private boolean isBeforeFirstMapNotify = false; // Is the window (being shown) between // setVisible(true) & handleMapNotify(). + /** + * The type of the window. + * + * The type is supposed to be immutable while the peer object exists. + * The value gets initialized in the preInit() method. + */ + private Window.Type windowType = Window.Type.NORMAL; + + public final Window.Type getWindowType() { + return windowType; + } + // It need to be accessed from XFramePeer. protected Vector toplevelStateListeners = new Vector(); XWindowPeer(XCreateWindowParams params) { @@ -128,6 +146,7 @@ void preInit(XCreateWindowParams params) { target = (Component)params.get(TARGET); + windowType = ((Window)target).getType(); params.put(REPARENTED, Boolean.valueOf(isOverrideRedirect() || isSimpleWindow())); super.preInit(params); @@ -233,7 +252,7 @@ if (((Window)target).getWarningString() != null) { // accessSystemTray permission allows to display TrayIcon, TrayIcon tooltip // and TrayIcon balloon windows without a warning window. - if (!WindowAccessor.isTrayIconWindow((Window)target)) { + if (!AWTAccessor.getWindowAccessor().isTrayIconWindow((Window)target)) { warningWindow = new XWarningWindow((Window)target, getWindow(), this); } } @@ -525,7 +544,7 @@ boolean isAutoRequestFocus() { if (XToolkit.isToolkitThread()) { - return WindowAccessor.isAutoRequestFocus((Window)target); + return AWTAccessor.getWindowAccessor().isAutoRequestFocus((Window)target); } else { return ((Window)target).isAutoRequestFocus(); } @@ -1065,10 +1084,11 @@ if (warningWindow != null) { // We can't use the coordinates stored in the XBaseWindow since // they are zeros for decorated frames. - int x = ComponentAccessor.getX(target); - int y = ComponentAccessor.getY(target); - int width = ComponentAccessor.getWidth(target); - int height = ComponentAccessor.getHeight(target); + AWTAccessor.ComponentAccessor compAccessor = AWTAccessor.getComponentAccessor(); + int x = compAccessor.getX(target); + int y = compAccessor.getY(target); + int width = compAccessor.getWidth(target); + int height = compAccessor.getHeight(target); warningWindow.reposition(x, y, width, height); } } @@ -1119,9 +1139,8 @@ } boolean isOverrideRedirect() { - return (XWM.getWMID() == XWM.OPENLOOK_WM ? true : false) || - ((XToolkit)Toolkit.getDefaultToolkit()).isOverrideRedirect((Window)target) || - XTrayIconPeer.isTrayIconStuffWindow((Window)target); + return XWM.getWMID() == XWM.OPENLOOK_WM || + Window.Type.POPUP.equals(getWindowType()); } final boolean isOLWMDecorBug() { @@ -1152,7 +1171,7 @@ if (isSimpleWindow()) { if (target == XKeyboardFocusManagerPeer.getCurrentNativeFocusedWindow()) { Window owner = getDecoratedOwner((Window)target); - ((XWindowPeer)ComponentAccessor.getPeer(owner)).requestWindowFocus(); + ((XWindowPeer)AWTAccessor.getComponentAccessor().getPeer(owner)).requestWindowFocus(); } } } @@ -1183,7 +1202,77 @@ } } + private void removeStartupNotification() { + if (isStartupNotificationRemoved.getAndSet(true)) { + return; + } + + final String desktopStartupId = AccessController.doPrivileged(new PrivilegedAction() { + public String run() { + return XToolkit.getEnv("DESKTOP_STARTUP_ID"); + } + }); + if (desktopStartupId == null) { + return; + } + + final StringBuilder messageBuilder = new StringBuilder("remove: ID="); + messageBuilder.append('"'); + for (int i = 0; i < desktopStartupId.length(); i++) { + if (desktopStartupId.charAt(i) == '"' || desktopStartupId.charAt(i) == '\\') { + messageBuilder.append('\\'); + } + messageBuilder.append(desktopStartupId.charAt(i)); + } + messageBuilder.append('"'); + messageBuilder.append('\0'); + final byte[] message; + try { + message = messageBuilder.toString().getBytes("UTF-8"); + } catch (UnsupportedEncodingException cannotHappen) { + return; + } + + XClientMessageEvent req = null; + + XToolkit.awtLock(); + try { + final XAtom netStartupInfoBeginAtom = XAtom.get("_NET_STARTUP_INFO_BEGIN"); + final XAtom netStartupInfoAtom = XAtom.get("_NET_STARTUP_INFO"); + + req = new XClientMessageEvent(); + req.set_type(XConstants.ClientMessage); + req.set_window(getWindow()); + req.set_message_type(netStartupInfoBeginAtom.getAtom()); + req.set_format(8); + + for (int pos = 0; pos < message.length; pos += 20) { + final int msglen = Math.min(message.length - pos, 20); + int i = 0; + for (; i < msglen; i++) { + XlibWrapper.unsafe.putByte(req.get_data() + i, message[pos + i]); + } + for (; i < 20; i++) { + XlibWrapper.unsafe.putByte(req.get_data() + i, (byte)0); + } + XlibWrapper.XSendEvent(XToolkit.getDisplay(), + XlibWrapper.RootWindow(XToolkit.getDisplay(), getScreenNumber()), + false, + XConstants.PropertyChangeMask, + req.pData); + req.set_message_type(netStartupInfoAtom.getAtom()); + } + } finally { + XToolkit.awtUnlock(); + if (req != null) { + req.dispose(); + } + } + } + public void handleMapNotifyEvent(XEvent xev) { + removeStartupNotification(); + // See 6480534. isUnhiding |= isWMStateNetHidden(); @@ -1309,7 +1398,7 @@ XToolkit.awtLock(); try { if (isReparented() && delayedModalBlocking) { - addToTransientFors((XDialogPeer) ComponentAccessor.getPeer(modalBlocker)); + addToTransientFors((XDialogPeer) AWTAccessor.getComponentAccessor().getPeer(modalBlocker)); delayedModalBlocking = false; } } finally { @@ -1393,7 +1482,7 @@ try { // State lock should always be after awtLock synchronized(getStateLock()) { - XDialogPeer blockerPeer = (XDialogPeer) ComponentAccessor.getPeer(d); + XDialogPeer blockerPeer = (XDialogPeer) AWTAccessor.getComponentAccessor().getPeer(d); if (blocked) { log.fine("{0} is blocked by {1}", this, blockerPeer); modalBlocker = d; @@ -1673,7 +1762,7 @@ // current chain iterator in the order from next to prev XWindowPeer chainToSplit = prevTransientFor; while (chainToSplit != null) { - XWindowPeer blocker = (XWindowPeer) ComponentAccessor.getPeer(chainToSplit.modalBlocker); + XWindowPeer blocker = (XWindowPeer) AWTAccessor.getComponentAccessor().getPeer(chainToSplit.modalBlocker); if (thisChainBlockers.contains(blocker)) { // add to this dialog's chain setToplevelTransientFor(thisChain, chainToSplit, true, false); @@ -1701,7 +1790,7 @@ static Window getDecoratedOwner(Window window) { while ((null != window) && !(window instanceof Frame || window instanceof Dialog)) { - window = (Window) ComponentAccessor.getParent_NoClientCode(window); + window = (Window) AWTAccessor.getComponentAccessor().getParent(window); } return window; } @@ -1734,7 +1823,7 @@ } focusLog.fine("Parent window is not active"); - XDecoratedPeer wpeer = (XDecoratedPeer)ComponentAccessor.getPeer(ownerWindow); + XDecoratedPeer wpeer = (XDecoratedPeer)AWTAccessor.getComponentAccessor().getPeer(ownerWindow); if (wpeer != null && wpeer.requestWindowFocus(this, time, timeProvided)) { focusLog.fine("Parent window accepted focus request - generating focus for this window"); return true; @@ -1747,12 +1836,49 @@ void setActualFocusedWindow(XWindowPeer actualFocusedWindow) { } + /** + * Applies the current window type. + */ + private void applyWindowType() { + XNETProtocol protocol = XWM.getWM().getNETProtocol(); + if (protocol == null) { + return; + } + + XAtom typeAtom = null; + + switch (getWindowType()) + { + case NORMAL: + typeAtom = protocol.XA_NET_WM_WINDOW_TYPE_NORMAL; + break; + case UTILITY: + typeAtom = protocol.XA_NET_WM_WINDOW_TYPE_UTILITY; + break; + case POPUP: + typeAtom = protocol.XA_NET_WM_WINDOW_TYPE_POPUP_MENU; + break; + } + + if (typeAtom != null) { + XAtomList wtype = new XAtomList(); + wtype.add(typeAtom); + protocol.XA_NET_WM_WINDOW_TYPE. + setAtomListProperty(getWindow(), wtype); + } else { + protocol.XA_NET_WM_WINDOW_TYPE. + DeleteProperty(getWindow()); + } + } + + @Override public void xSetVisible(boolean visible) { if (log.isLoggable(PlatformLogger.FINE)) log.fine("Setting visible on " + this + " to " + visible); XToolkit.awtLock(); try { this.visible = visible; if (visible) { + applyWindowType(); XlibWrapper.XMapRaised(XToolkit.getDisplay(), getWindow()); } else { XlibWrapper.XUnmapWindow(XToolkit.getDisplay(), getWindow()); @@ -2027,9 +2153,9 @@ if (toplevel != null) { Window w = (Window)toplevel.target; while (w != null && toplevel != this && !(toplevel instanceof XDialogPeer)) { - w = (Window) ComponentAccessor.getParent_NoClientCode(w); + w = (Window) AWTAccessor.getComponentAccessor().getParent(w); if (w != null) { - toplevel = (XWindowPeer) ComponentAccessor.getPeer(w); + toplevel = (XWindowPeer) AWTAccessor.getComponentAccessor().getPeer(w); } } if (w == null || (w != this.target && w instanceof Dialog)) { diff -r feacdd1c5df3 -r 1411f4ebf52e jdk/src/solaris/classes/sun/awt/X11/XlibWrapper.java --- a/jdk/src/solaris/classes/sun/awt/X11/XlibWrapper.java Thu Dec 10 09:43:48 2009 -0800 +++ b/jdk/src/solaris/classes/sun/awt/X11/XlibWrapper.java Thu Dec 10 09:46:13 2009 -0800 @@ -353,6 +353,8 @@ static native String ServerVendor(long display); static native int VendorRelease(long display); static native boolean IsXsunKPBehavior(long display); + static native boolean IsSunKeyboard(long display); + static native boolean IsKanaKeyboard(long display); static native void XBell(long display, int percent); @@ -513,8 +515,9 @@ long keysym_uppercase); static native long XGetModifierMapping(long display); + static native void XFreeModifiermap(long keymap); + static native void XRefreshKeyboardMapping(long event); - static native void XFreeModifiermap(long keymap); static native void XChangeActivePointerGrab(long display, int mask, long cursor, long time); diff -r feacdd1c5df3 -r 1411f4ebf52e jdk/src/solaris/classes/sun/awt/X11/keysym2ucs.h --- a/jdk/src/solaris/classes/sun/awt/X11/keysym2ucs.h Thu Dec 10 09:43:48 2009 -0800 +++ b/jdk/src/solaris/classes/sun/awt/X11/keysym2ucs.h Thu Dec 10 09:46:13 2009 -0800 @@ -107,6 +107,8 @@ tojava static Hashtable javaKeycode2KeysymHash = new Hashtable(); tojava static long keysym_lowercase = unsafe.allocateMemory(Native.getLongSize()); tojava static long keysym_uppercase = unsafe.allocateMemory(Native.getLongSize()); +tojava static Keysym2JavaKeycode kanaLock = new Keysym2JavaKeycode(java.awt.event.KeyEvent.VK_KANA_LOCK, +tojava java.awt.event.KeyEvent.KEY_LOCATION_STANDARD); tojava private static PlatformLogger keyEventLog = PlatformLogger.getLogger("sun.awt.X11.kye.XKeysym"); tojava public static char convertKeysym( long ks, int state ) { tojava @@ -252,12 +254,35 @@ tojava } tojava return keysym; tojava } +tojava +tojava /** +tojava Return java.awt.KeyEvent constant meaning (Java) keycode, derived from X keysym. +tojava Some keysyms maps to more than one keycode, these would require extra processing. +tojava */ +tojava static Keysym2JavaKeycode getJavaKeycode( long keysym ) { +tojava if(keysym == XKeySymConstants.XK_Mode_switch){ +tojava /* XK_Mode_switch on solaris maps either to VK_ALT_GRAPH (default) or VK_KANA_LOCK */ +tojava if( XToolkit.isKanaKeyboard() ) { +tojava return kanaLock; +tojava } +tojava }else if(keysym == XKeySymConstants.XK_L1){ +tojava /* if it is Sun keyboard, trick hash to return VK_STOP else VK_F11 (default) */ +tojava if( XToolkit.isSunKeyboard() ) { +tojava keysym = XKeySymConstants.SunXK_Stop; +tojava } +tojava }else if(keysym == XKeySymConstants.XK_L2) { +tojava /* if it is Sun keyboard, trick hash to return VK_AGAIN else VK_F12 (default) */ +tojava if( XToolkit.isSunKeyboard() ) { +tojava keysym = XKeySymConstants.SunXK_Again; +tojava } +tojava } +tojava +tojava return keysym2JavaKeycodeHash.get( keysym ); +tojava } tojava /** tojava Return java.awt.KeyEvent constant meaning (Java) keycode, derived from X Window KeyEvent. tojava Algorithm is, extract via XKeycodeToKeysym a proper keysym according to Xlib spec rules and tojava err exceptions, then search a java keycode in a table. -tojava Some keysyms maps to more than one keycode, these would require extra processing. If someone -tojava points me to such a keysym. tojava */ tojava static Keysym2JavaKeycode getJavaKeycode( XKeyEvent ev ) { tojava // get from keysym2JavaKeycodeHash. @@ -272,7 +297,7 @@ tojava keysym = xkeycode2keysym(ev, ndx); tojava } tojava -tojava Keysym2JavaKeycode jkc = keysym2JavaKeycodeHash.get( keysym ); +tojava Keysym2JavaKeycode jkc = getJavaKeycode( keysym ); tojava return jkc; tojava } tojava static int getJavaKeycodeOnly( XKeyEvent ev ) { @@ -297,7 +322,7 @@ tojava ndx = 0; tojava keysym = xkeycode2keysym_noxkb(ev, ndx); tojava } -tojava Keysym2JavaKeycode jkc = keysym2JavaKeycodeHash.get( keysym ); +tojava Keysym2JavaKeycode jkc = getJavaKeycode( keysym ); tojava return jkc == null ? java.awt.event.KeyEvent.VK_UNDEFINED : jkc.getJavaKeycode(); tojava } tojava static long javaKeycode2Keysym( int jkey ) { diff -r feacdd1c5df3 -r 1411f4ebf52e jdk/src/solaris/lib/flavormap.properties --- a/jdk/src/solaris/lib/flavormap.properties Thu Dec 10 09:43:48 2009 -0800 +++ b/jdk/src/solaris/lib/flavormap.properties Thu Dec 10 09:46:13 2009 -0800 @@ -73,5 +73,6 @@ TEXT=text/plain;eoln="\n";terminators=0 STRING=text/plain;charset=iso8859-1;eoln="\n";terminators=0 FILE_NAME=application/x-java-file-list;class=java.util.List +text/uri-list=application/x-java-file-list;class=java.util.List PNG=image/x-java-image;class=java.awt.Image JFIF=image/x-java-image;class=java.awt.Image diff -r feacdd1c5df3 -r 1411f4ebf52e jdk/src/solaris/native/sun/xawt/XlibWrapper.c --- a/jdk/src/solaris/native/sun/xawt/XlibWrapper.c Thu Dec 10 09:43:48 2009 -0800 +++ b/jdk/src/solaris/native/sun/xawt/XlibWrapper.c Thu Dec 10 09:46:13 2009 -0800 @@ -33,6 +33,7 @@ #include #include #include +#include #include #include @@ -1214,6 +1215,48 @@ } } + +JNIEXPORT jboolean JNICALL Java_sun_awt_X11_XlibWrapper_IsSunKeyboard +(JNIEnv *env, jclass clazz, jlong display) +{ + int xx; + AWT_CHECK_HAVE_LOCK(); + xx = XKeysymToKeycode((Display*)jlong_to_ptr(display), SunXK_F37); + return (!xx) ? JNI_FALSE : JNI_TRUE; +} + +JNIEXPORT jboolean JNICALL Java_sun_awt_X11_XlibWrapper_IsKanaKeyboard +(JNIEnv *env, jclass clazz, jlong display) +{ + int xx; + AWT_CHECK_HAVE_LOCK(); + static jboolean result = JNI_FALSE; + + int32_t minKeyCode, maxKeyCode, keySymsPerKeyCode; + KeySym *keySyms, *keySymsStart, keySym; + int32_t i; + int32_t kanaCount = 0; + + // There's no direct way to determine whether the keyboard has + // a kana lock key. From available keyboard mapping tables, it looks + // like only keyboards with the kana lock key can produce keysyms + // for kana characters. So, as an indirect test, we check for those. + XDisplayKeycodes((Display*)jlong_to_ptr(display), &minKeyCode, &maxKeyCode); + keySyms = XGetKeyboardMapping((Display*)jlong_to_ptr(display), minKeyCode, maxKeyCode - minKeyCode + 1, &keySymsPerKeyCode); + keySymsStart = keySyms; + for (i = 0; i < (maxKeyCode - minKeyCode + 1) * keySymsPerKeyCode; i++) { + keySym = *keySyms++; + if ((keySym & 0xff00) == 0x0400) { + kanaCount++; + } + } + XFree(keySymsStart); + + // use a (somewhat arbitrary) minimum so we don't get confused by a stray function key + result = kanaCount > 10; + return result ? JNI_TRUE : JNI_FALSE; +} + JavaVM* jvm = NULL; static int ToolkitErrorHandler(Display * dpy, XErrorEvent * event) { if (jvm != NULL) { @@ -1261,6 +1304,7 @@ return (*(XErrorHandler)jlong_to_ptr(handler))((Display*) jlong_to_ptr(display), (XErrorEvent*) jlong_to_ptr(event_ptr)); } + /* * Class: sun_awt_X11_XlibWrapper * Method: PrintXErrorEvent @@ -1853,6 +1897,17 @@ AWT_CHECK_HAVE_LOCK(); XFreeModifiermap((XModifierKeymap*) jlong_to_ptr(keymap)); } +/* + * Class: sun_awt_X11_XlibWrapper + * Method: XRefreshKeyboardMapping + * Signature: (J)V + */ +JNIEXPORT void JNICALL Java_sun_awt_X11_XlibWrapper_XRefreshKeyboardMapping +(JNIEnv *env, jclass clazz, jlong event_ptr) +{ + AWT_CHECK_HAVE_LOCK(); + XRefreshKeyboardMapping((XMappingEvent*) jlong_to_ptr(event_ptr)); +} JNIEXPORT void JNICALL Java_sun_awt_X11_XlibWrapper_XChangeActivePointerGrab(JNIEnv *env, jclass clazz, diff -r feacdd1c5df3 -r 1411f4ebf52e jdk/src/windows/classes/sun/awt/windows/WCanvasPeer.java --- a/jdk/src/windows/classes/sun/awt/windows/WCanvasPeer.java Thu Dec 10 09:43:48 2009 -0800 +++ b/jdk/src/windows/classes/sun/awt/windows/WCanvasPeer.java Thu Dec 10 09:46:13 2009 -0800 @@ -28,8 +28,6 @@ import java.awt.peer.*; import java.lang.ref.WeakReference; import java.lang.reflect.Method; -import sun.awt.AWTAccessor; -import sun.awt.ComponentAccessor; import sun.awt.SunToolkit; import sun.awt.Win32GraphicsDevice; import sun.awt.PaintEventDispatcher; diff -r feacdd1c5df3 -r 1411f4ebf52e jdk/src/windows/classes/sun/awt/windows/WComponentPeer.java --- a/jdk/src/windows/classes/sun/awt/windows/WComponentPeer.java Thu Dec 10 09:43:48 2009 -0800 +++ b/jdk/src/windows/classes/sun/awt/windows/WComponentPeer.java Thu Dec 10 09:46:13 2009 -0800 @@ -57,7 +57,7 @@ import java.awt.dnd.DropTarget; import java.awt.dnd.peer.DropTargetPeer; -import sun.awt.ComponentAccessor; +import sun.awt.AWTAccessor; import sun.util.logging.PlatformLogger; @@ -817,7 +817,7 @@ } private void postPaintIfNecessary(int x, int y, int w, int h) { - if ( !ComponentAccessor.getIgnoreRepaint( (Component) target) ) { + if ( !AWTAccessor.getComponentAccessor().getIgnoreRepaint( (Component) target) ) { PaintEvent event = PaintEventDispatcher.getPaintEventDispatcher(). createPaintEvent((Component)target, x, y, w, h); if (event != null) { diff -r feacdd1c5df3 -r 1411f4ebf52e jdk/src/windows/classes/sun/awt/windows/WDataTransferer.java --- a/jdk/src/windows/classes/sun/awt/windows/WDataTransferer.java Thu Dec 10 09:43:48 2009 -0800 +++ b/jdk/src/windows/classes/sun/awt/windows/WDataTransferer.java Thu Dec 10 09:46:13 2009 -0800 @@ -72,6 +72,10 @@ import sun.awt.image.ImageRepresentation; import sun.awt.image.ToolkitImage; +import java.util.ArrayList; + +import java.io.ByteArrayOutputStream; + /** * Platform-specific support for the data transfer subsystem. * @@ -342,6 +346,33 @@ return imageDataToPlatformImageBytes(imageData, width, height, format); } + private static final byte [] UNICODE_NULL_TERMINATOR = new byte [] {0,0}; + + protected ByteArrayOutputStream convertFileListToBytes(ArrayList fileList) + throws IOException + { + ByteArrayOutputStream bos = new ByteArrayOutputStream(); + + if(fileList.isEmpty()) { + //store empty unicode string (null terminator) + bos.write(UNICODE_NULL_TERMINATOR); + } else { + for (int i = 0; i < fileList.size(); i++) { + byte[] bytes = fileList.get(i).getBytes(getDefaultUnicodeEncoding()); + //store unicode string with null terminator + bos.write(bytes, 0, bytes.length); + bos.write(UNICODE_NULL_TERMINATOR); + } + } + + // According to MSDN the byte array have to be double NULL-terminated. + // The array contains Unicode characters, so each NULL-terminator is + // a pair of bytes + + bos.write(UNICODE_NULL_TERMINATOR); + return bos; + } + /** * Returns a byte array which contains data special for the given format * and for the given image data. diff -r feacdd1c5df3 -r 1411f4ebf52e jdk/src/windows/classes/sun/awt/windows/WDialogPeer.java --- a/jdk/src/windows/classes/sun/awt/windows/WDialogPeer.java Thu Dec 10 09:43:48 2009 -0800 +++ b/jdk/src/windows/classes/sun/awt/windows/WDialogPeer.java Thu Dec 10 09:46:13 2009 -0800 @@ -53,7 +53,12 @@ } } - native void create(WComponentPeer parent); + native void createAwtDialog(WComponentPeer parent); + void create(WComponentPeer parent) { + preCreate(parent); + createAwtDialog(parent); + } + native void showModal(); native void endModal(); @@ -93,7 +98,7 @@ public void blockWindows(java.util.List toBlock) { for (Window w : toBlock) { - WWindowPeer wp = (WWindowPeer)ComponentAccessor.getPeer(w); + WWindowPeer wp = (WWindowPeer)AWTAccessor.getComponentAccessor().getPeer(w); if (wp != null) { wp.setModalBlocked((Dialog)target, true); } diff -r feacdd1c5df3 -r 1411f4ebf52e jdk/src/windows/classes/sun/awt/windows/WFileDialogPeer.java --- a/jdk/src/windows/classes/sun/awt/windows/WFileDialogPeer.java Thu Dec 10 09:43:48 2009 -0800 +++ b/jdk/src/windows/classes/sun/awt/windows/WFileDialogPeer.java Thu Dec 10 09:46:13 2009 -0800 @@ -35,7 +35,7 @@ import java.util.MissingResourceException; import java.util.Vector; import sun.awt.AppContext; -import sun.awt.ComponentAccessor; +import sun.awt.AWTAccessor; public class WFileDialogPeer extends WWindowPeer implements FileDialogPeer { @@ -187,7 +187,7 @@ public void blockWindows(java.util.List toBlock) { for (Window w : toBlock) { - WWindowPeer wp = (WWindowPeer)ComponentAccessor.getPeer(w); + WWindowPeer wp = (WWindowPeer)AWTAccessor.getComponentAccessor().getPeer(w); if (wp != null) { blockWindow(wp); } diff -r feacdd1c5df3 -r 1411f4ebf52e jdk/src/windows/classes/sun/awt/windows/WFramePeer.java --- a/jdk/src/windows/classes/sun/awt/windows/WFramePeer.java Thu Dec 10 09:43:48 2009 -0800 +++ b/jdk/src/windows/classes/sun/awt/windows/WFramePeer.java Thu Dec 10 09:46:13 2009 -0800 @@ -136,6 +136,7 @@ native void createAwtFrame(WComponentPeer parent); void create(WComponentPeer parent) { + preCreate(parent); createAwtFrame(parent); } diff -r feacdd1c5df3 -r 1411f4ebf52e jdk/src/windows/classes/sun/awt/windows/WPrintDialogPeer.java --- a/jdk/src/windows/classes/sun/awt/windows/WPrintDialogPeer.java Thu Dec 10 09:43:48 2009 -0800 +++ b/jdk/src/windows/classes/sun/awt/windows/WPrintDialogPeer.java Thu Dec 10 09:46:13 2009 -0800 @@ -31,7 +31,7 @@ import java.awt.dnd.DropTarget; import java.util.Vector; import sun.awt.AppContext; -import sun.awt.ComponentAccessor; +import sun.awt.AWTAccessor; public class WPrintDialogPeer extends WWindowPeer implements DialogPeer { @@ -103,7 +103,7 @@ public void blockWindows(java.util.List toBlock) { for (Window w : toBlock) { - WWindowPeer wp = (WWindowPeer)ComponentAccessor.getPeer(w); + WWindowPeer wp = (WWindowPeer)AWTAccessor.getComponentAccessor().getPeer(w); if (wp != null) { blockWindow(wp); } diff -r feacdd1c5df3 -r 1411f4ebf52e jdk/src/windows/classes/sun/awt/windows/WWindowPeer.java --- a/jdk/src/windows/classes/sun/awt/windows/WWindowPeer.java Thu Dec 10 09:43:48 2009 -0800 +++ b/jdk/src/windows/classes/sun/awt/windows/WWindowPeer.java Thu Dec 10 09:46:13 2009 -0800 @@ -199,7 +199,17 @@ } native void createAwtWindow(WComponentPeer parent); + + private volatile Window.Type windowType = Window.Type.NORMAL; + + // This method must be called for Window, Dialog, and Frame before creating + // the hwnd + void preCreate(WComponentPeer parent) { + windowType = ((Window)target).getType(); + } + void create(WComponentPeer parent) { + preCreate(parent); createAwtWindow(parent); } diff -r feacdd1c5df3 -r 1411f4ebf52e jdk/src/windows/native/sun/windows/awt_Dialog.cpp --- a/jdk/src/windows/native/sun/windows/awt_Dialog.cpp Thu Dec 10 09:43:48 2009 -0800 +++ b/jdk/src/windows/native/sun/windows/awt_Dialog.cpp Thu Dec 10 09:46:13 2009 -0800 @@ -760,7 +760,7 @@ * Signature: (Lsun/awt/windows/WComponentPeer;)V */ JNIEXPORT void JNICALL -Java_sun_awt_windows_WDialogPeer_create(JNIEnv *env, jobject self, +Java_sun_awt_windows_WDialogPeer_createAwtDialog(JNIEnv *env, jobject self, jobject parent) { TRY; diff -r feacdd1c5df3 -r 1411f4ebf52e jdk/src/windows/native/sun/windows/awt_DnDDS.cpp --- a/jdk/src/windows/native/sun/windows/awt_DnDDS.cpp Thu Dec 10 09:43:48 2009 -0800 +++ b/jdk/src/windows/native/sun/windows/awt_DnDDS.cpp Thu Dec 10 09:46:13 2009 -0800 @@ -648,7 +648,7 @@ dropfiles->pt.x = m_dropPoint.x; dropfiles->pt.y = m_dropPoint.y; dropfiles->fNC = m_fNC; - dropfiles->fWide = FALSE; // good guess! + dropfiles->fWide = TRUE; // good guess! dataout += sizeof(DROPFILES); } @@ -815,7 +815,7 @@ dropfiles->pt.x = m_dropPoint.x; dropfiles->pt.y = m_dropPoint.y; dropfiles->fNC = m_fNC; - dropfiles->fWide = FALSE; // good guess! + dropfiles->fWide = TRUE; // good guess! dataout += sizeof(DROPFILES); } diff -r feacdd1c5df3 -r 1411f4ebf52e jdk/src/windows/native/sun/windows/awt_Toolkit.cpp --- a/jdk/src/windows/native/sun/windows/awt_Toolkit.cpp Thu Dec 10 09:43:48 2009 -0800 +++ b/jdk/src/windows/native/sun/windows/awt_Toolkit.cpp Thu Dec 10 09:46:13 2009 -0800 @@ -1518,6 +1518,7 @@ return defaultIconSm; } +// The icon at index 0 must be gray. See AwtWindow::GetSecurityWarningIcon() HICON AwtToolkit::GetSecurityWarningIcon(UINT index, UINT w, UINT h) { //Note: should not exceed 10 because of the current implementation. diff -r feacdd1c5df3 -r 1411f4ebf52e jdk/src/windows/native/sun/windows/awt_Window.cpp --- a/jdk/src/windows/native/sun/windows/awt_Window.cpp Thu Dec 10 09:43:48 2009 -0800 +++ b/jdk/src/windows/native/sun/windows/awt_Window.cpp Thu Dec 10 09:46:13 2009 -0800 @@ -163,9 +163,11 @@ jfieldID AwtWindow::sysYID; jfieldID AwtWindow::sysWID; jfieldID AwtWindow::sysHID; +jfieldID AwtWindow::windowTypeID; jmethodID AwtWindow::getWarningStringMID; jmethodID AwtWindow::calculateSecurityWarningPositionMID; +jmethodID AwtWindow::windowTypeNameMID; int AwtWindow::ms_instanceCounter = 0; HHOOK AwtWindow::ms_hCBTFilter; @@ -216,6 +218,9 @@ hContentBitmap = NULL; ::InitializeCriticalSection(&contentBitmapCS); + + m_windowType = Type::NORMAL; + m_alwaysOnTop = false; } AwtWindow::~AwtWindow() @@ -348,10 +353,10 @@ RECT rect; CalculateWarningWindowBounds(env, &rect); - ::SetWindowPos(warningWindow, HWND_NOTOPMOST, + ::SetWindowPos(warningWindow, IsAlwaysOnTop() ? HWND_TOPMOST : GetHWnd(), rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top, - SWP_ASYNCWINDOWPOS | SWP_NOACTIVATE | SWP_NOZORDER | + SWP_ASYNCWINDOWPOS | SWP_NOACTIVATE | SWP_NOOWNERZORDER ); } @@ -475,6 +480,9 @@ } env->DeleteLocalRef(target); + InitType(env, peer); + TweakStyle(windowStyle, windowExStyle); + AwtCanvas::CreateHWnd(env, title, windowStyle, windowExStyle, @@ -645,7 +653,10 @@ HICON AwtWindow::GetSecurityWarningIcon() { - HICON ico = AwtToolkit::GetInstance().GetSecurityWarningIcon(securityWarningAnimationStage, + // It is assumed that the icon at index 0 is gray + const UINT index = securityAnimationKind == akShow ? + securityWarningAnimationStage : 0; + HICON ico = AwtToolkit::GetInstance().GetSecurityWarningIcon(index, warningWindowWidth, warningWindowHeight); return ico; } @@ -821,7 +832,9 @@ securityAnimationTimerElapse, NULL); if (securityAnimationKind == akShow) { - ::SetWindowPos(warningWindow, HWND_NOTOPMOST, 0, 0, 0, 0, + ::SetWindowPos(warningWindow, + IsAlwaysOnTop() ? HWND_TOPMOST : GetHWnd(), + 0, 0, 0, 0, SWP_NOACTIVATE | SWP_NOSIZE | SWP_NOMOVE | SWP_SHOWWINDOW | SWP_NOOWNERZORDER); @@ -982,6 +995,50 @@ delete rsws; } +void AwtWindow::InitType(JNIEnv *env, jobject peer) +{ + jobject type = env->GetObjectField(peer, windowTypeID); + if (type == NULL) { + return; + } + + jstring value = (jstring)env->CallObjectMethod(type, windowTypeNameMID); + if (value == NULL) { + env->DeleteLocalRef(type); + return; + } + + const char* valueNative = env->GetStringUTFChars(value, 0); + if (valueNative == NULL) { + env->DeleteLocalRef(value); + env->DeleteLocalRef(type); + return; + } + + if (strcmp(valueNative, "UTILITY") == 0) { + m_windowType = Type::UTILITY; + } else if (strcmp(valueNative, "POPUP") == 0) { + m_windowType = Type::POPUP; + } + + env->ReleaseStringUTFChars(value, valueNative); + env->DeleteLocalRef(value); + env->DeleteLocalRef(type); +} + +void AwtWindow::TweakStyle(DWORD & style, DWORD & exStyle) +{ + switch (GetType()) { + case Type::UTILITY: + exStyle |= WS_EX_TOOLWINDOW; + break; + case Type::POPUP: + style &= ~WS_OVERLAPPED; + style |= WS_POPUP; + break; + } +} + /* Create a new AwtWindow object and window. */ AwtWindow* AwtWindow::Create(jobject self, jobject parent) { @@ -2216,6 +2273,7 @@ if (::IsWindow(w->GetHWnd())) { w->SendMessage(WM_AWT_SETALWAYSONTOP, (WPARAM)value, (LPARAM)w); + w->m_alwaysOnTop = (bool)value; } ret: env->DeleteGlobalRef(self); @@ -3008,6 +3066,11 @@ AwtWindow::calculateSecurityWarningPositionMID = env->GetMethodID(cls, "calculateSecurityWarningPosition", "(DDDD)Ljava/awt/geom/Point2D;"); + jclass windowTypeClass = env->FindClass("java/awt/Window$Type"); + AwtWindow::windowTypeNameMID = + env->GetMethodID(windowTypeClass, "name", "()Ljava/lang/String;"); + env->DeleteLocalRef(windowTypeClass); + CATCH_BAD_ALLOC; } @@ -3035,6 +3098,9 @@ AwtWindow::sysWID = env->GetFieldID(cls, "sysW", "I"); AwtWindow::sysHID = env->GetFieldID(cls, "sysH", "I"); + AwtWindow::windowTypeID = env->GetFieldID(cls, "windowType", + "Ljava/awt/Window$Type;"); + CATCH_BAD_ALLOC; } diff -r feacdd1c5df3 -r 1411f4ebf52e jdk/src/windows/native/sun/windows/awt_Window.h --- a/jdk/src/windows/native/sun/windows/awt_Window.h Thu Dec 10 09:43:48 2009 -0800 +++ b/jdk/src/windows/native/sun/windows/awt_Window.h Thu Dec 10 09:46:13 2009 -0800 @@ -63,8 +63,11 @@ static jfieldID sysWID; static jfieldID sysHID; + static jfieldID windowTypeID; + static jmethodID getWarningStringMID; static jmethodID calculateSecurityWarningPositionMID; + static jmethodID windowTypeNameMID; AwtWindow(); virtual ~AwtWindow(); @@ -362,10 +365,28 @@ void EnableTranslucency(BOOL enable); + // Native representation of the java.awt.Window.Type enum + enum Type { + NORMAL, UTILITY, POPUP + }; + + inline Type GetType() { return m_windowType; } + private: int m_screenNum; void InitOwner(AwtWindow *owner); + + Type m_windowType; + void InitType(JNIEnv *env, jobject peer); + + // Tweak the style according to the type of the window + void TweakStyle(DWORD & style, DWORD & exStyle); + + // Set in _SetAlwaysOnTop() + bool m_alwaysOnTop; +public: + inline bool IsAlwaysOnTop() { return m_alwaysOnTop; } }; #endif /* AWT_WINDOW_H */ diff -r feacdd1c5df3 -r 1411f4ebf52e jdk/test/java/awt/EventQueue/PushPopDeadlock2/PushPopTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/java/awt/EventQueue/PushPopDeadlock2/PushPopTest.java Thu Dec 10 09:46:13 2009 -0800 @@ -0,0 +1,103 @@ +/* + * Copyright 2009 Sun Microsystems, Inc. All Rights Reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +/* + @test + @bug 4913324 + @author Oleg Sukhodolsky: area=eventqueue + @run main/timeout=30 PushPopTest +*/ + +import java.awt.*; +import java.awt.event.*; +import java.util.EmptyStackException; +import sun.awt.SunToolkit; + +public class PushPopTest { + + public static Frame frame; + public static void main(String[] args) { + frame = new Frame(""); + frame.pack(); + + Runnable dummy = new Runnable() { + public void run() { + System.err.println("Dummy is here."); + } + }; + EventQueue seq = Toolkit.getDefaultToolkit().getSystemEventQueue(); + MyEventQueue1 eq1 = new MyEventQueue1(); + MyEventQueue2 eq2 = new MyEventQueue2(); + EventQueue.invokeLater(dummy); + + seq.push(eq1); + EventQueue.invokeLater(dummy); + + eq1.push(eq2); + EventQueue.invokeLater(dummy); + Runnable runnable = new Runnable() { + public void run() { + System.err.println("Dummy from SunToolkit"); + } + }; + InvocationEvent ie = new InvocationEvent(eq2, runnable, null, false); + System.err.println(ie); + SunToolkit.postEvent(SunToolkit.targetToAppContext(frame), ie); + eq1.pop(); + frame.dispose(); + } +} + +class MyEventQueue1 extends EventQueue { + + public void pop() throws EmptyStackException { + super.pop(); + } +} + +class MyEventQueue2 extends EventQueue { + + protected void pop() throws EmptyStackException { + System.err.println("pop2()"); + Thread.dumpStack(); + try { + EventQueue.invokeAndWait(new Runnable() { + public void run() { + Runnable runnable = new Runnable() { + public void run() { + System.err.println("Dummy from here"); + } + }; + InvocationEvent ie = new InvocationEvent(MyEventQueue2.this, runnable, null, false); + SunToolkit.postEvent(SunToolkit.targetToAppContext(PushPopTest.frame), ie); + postEvent(ie); + } + }); + } catch (InterruptedException ie) { + ie.printStackTrace(); + } catch (java.lang.reflect.InvocationTargetException ie) { + ie.printStackTrace(); + } + super.pop(); + } +} diff -r feacdd1c5df3 -r 1411f4ebf52e jdk/test/java/awt/KeyboardFocusmanager/TypeAhead/TestDialogTypeAhead.java --- a/jdk/test/java/awt/KeyboardFocusmanager/TypeAhead/TestDialogTypeAhead.java Thu Dec 10 09:43:48 2009 -0800 +++ b/jdk/test/java/awt/KeyboardFocusmanager/TypeAhead/TestDialogTypeAhead.java Thu Dec 10 09:46:13 2009 -0800 @@ -50,13 +50,7 @@ import java.applet.Applet; import java.awt.*; -import java.lang.reflect.InvocationTargetException; import java.awt.event.*; -import java.awt.peer.DialogPeer; -import java.awt.peer.ComponentPeer; -import java.lang.reflect.Method; -import java.lang.reflect.Proxy; -import java.lang.reflect.InvocationHandler; import java.lang.reflect.InvocationTargetException; import test.java.awt.regtesthelpers.Util; @@ -94,11 +88,13 @@ } }, AWTEvent.KEY_EVENT_MASK); + KeyboardFocusManager.setCurrentKeyboardFocusManager(new TestKFM()); + this.setLayout (new BorderLayout ()); f = new Frame("frame"); b = new Button("press"); - d = new TestDialog(f, "dialog", true, robotSema); + d = new Dialog(f, "dialog", true); ok = new Button("ok"); d.add(ok); d.pack(); @@ -170,6 +166,11 @@ } catch (InterruptedException ie) { throw new RuntimeException("Interrupted!"); } + if (!robotSema.getState()) { + throw new RuntimeException("robotSema hasn't been triggered"); + } + + System.err.println("typing ahead"); robot.keyPress(KeyEvent.VK_SPACE); robot.keyRelease(KeyEvent.VK_SPACE); waitForIdle(); @@ -278,65 +279,14 @@ } } - // Fix for 6446952. - // In the process of showing the dialog we have to catch peer.show() call - // so that to trigger key events just before it gets invoked. - // We base on the fact that a modal dialog sets type-ahead markers - // before it calls 'show' on the peer. - // Posting the key events before dialog.setVisible(true) would be actually not - // good because it would be Ok to dispatch them to the current focus owner, - // not to the dialog. - class TestDialog extends Dialog { - ComponentPeer origDialogPeer; - ComponentPeer proxyInstPeer; - Semaphore trigger; - - TestDialog(Frame owner, String title, boolean modal, Semaphore trigger) { - super(owner, title, modal); - this.trigger = trigger; - } - public ComponentPeer getPeer() { - ComponentPeer ret = super.getPeer(); - if (ret == proxyInstPeer) { - return origDialogPeer; - } else { - return ret; - } - } + class TestKFM extends DefaultKeyboardFocusManager { + protected synchronized void enqueueKeyEvents(long after, + Component untilFocused) + { + super.enqueueKeyEvents(after, untilFocused); - public void addNotify() { - super.addNotify(); - replacePeer(); - } - - void replacePeer() { - origDialogPeer = getPeer(); - - InvocationHandler handler = new InvocationHandler() { - public Object invoke(Object proxy, Method method, Object[] args) { - if (method.getName() == "show") { - trigger.raise(); - } - - Object ret = null; - try { - ret = method.invoke(origDialogPeer, args); - } catch (IllegalAccessException iae) { - throw new Error("Test error.", iae); - } catch (InvocationTargetException ita) { - throw new Error("Test error.", ita); - } - return ret; - } - }; - - proxyInstPeer = (DialogPeer)Proxy.newProxyInstance( - DialogPeer.class.getClassLoader(), new Class[] {DialogPeer.class}, handler); - - try { - Util.getField(Component.class, "peer").set(d, proxyInstPeer); - } catch (IllegalAccessException iae) { - throw new Error("Test error.", iae); + if (untilFocused == TestDialogTypeAhead.this.ok) { + TestDialogTypeAhead.this.robotSema.raise(); } } } diff -r feacdd1c5df3 -r 1411f4ebf52e jdk/test/java/awt/Window/WindowType/WindowType.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/java/awt/Window/WindowType/WindowType.java Thu Dec 10 09:46:13 2009 -0800 @@ -0,0 +1,61 @@ +/* + * Copyright 2009 Sun Microsystems, Inc. All Rights Reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +/* + @test + @bug 6402325 + @summary Test showing windows of different types + @author anthony.petrov@sun.com: area=awt.toplevel + @library ../../regtesthelpers + @build Util + @run main WindowType +*/ + +import java.awt.*; +import test.java.awt.regtesthelpers.Util; + +/** + * WindowType.java + * Summary: Test showing windows of different types. + */ +public class WindowType { + private static void test(Window window, Window.Type type) { + window.setType(type); + + window.setVisible(true); + Util.waitForIdle(null); + window.setVisible(false); + } + + private static void test(Window.Type type) { + test(new Window((Frame)null), type); + test(new Frame(), type); + test(new Dialog((Frame)null), type); + } + + public static void main(String[] args) { + test(Window.Type.NORMAL); + test(Window.Type.UTILITY); + test(Window.Type.POPUP); + } +} diff -r feacdd1c5df3 -r 1411f4ebf52e jdk/test/java/awt/datatransfer/DragUnicodeBetweenJVMTest/AbsoluteComponentCenterCalculator.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/java/awt/datatransfer/DragUnicodeBetweenJVMTest/AbsoluteComponentCenterCalculator.java Thu Dec 10 09:46:13 2009 -0800 @@ -0,0 +1,34 @@ +/* + * Copyright 2009 Sun Microsystems, Inc. All Rights Reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +import java.awt.*; + +class AbsoluteComponentCenterCalculator { + private AbsoluteComponentCenterCalculator () {} + public static int calculateXCenterCoordinate(Component component) { + return (int)component.getLocationOnScreen().getX()+(component.getWidth()/2); + } + public static int calculateYCenterCoordinate(Component component) { + return (int)component.getLocationOnScreen().getY()+(component.getHeight()/2); + } +} diff -r feacdd1c5df3 -r 1411f4ebf52e jdk/test/java/awt/datatransfer/DragUnicodeBetweenJVMTest/DragUnicodeBetweenJVMTest.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/java/awt/datatransfer/DragUnicodeBetweenJVMTest/DragUnicodeBetweenJVMTest.html Thu Dec 10 09:46:13 2009 -0800 @@ -0,0 +1,25 @@ + + + + REG: DnD of File-List between JVM is broken for non ASCII file names - Win32 + + + +

DragUnicodeBetweenJVMTest
Bug ID: 5098433

+ +

This is an AUTOMATIC test, simply wait for completion

+ + + + diff -r feacdd1c5df3 -r 1411f4ebf52e jdk/test/java/awt/datatransfer/DragUnicodeBetweenJVMTest/DragUnicodeBetweenJVMTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/java/awt/datatransfer/DragUnicodeBetweenJVMTest/DragUnicodeBetweenJVMTest.java Thu Dec 10 09:46:13 2009 -0800 @@ -0,0 +1,193 @@ +/* + * Copyright 2009 Sun Microsystems, Inc. All Rights Reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +/* + test + @bug 5098433 + @summary REG: DnD of File-List between JVM is broken for non ASCII file names - Win32 + @author Denis Fokin: area=dnd + @library ../../regtesthelpers + @library ../../regtesthelpers/process + @build Util + @build ProcessResults ProcessCommunicator + + + @run applet/othervm DragUnicodeBetweenJVMTest.html +*/ + +/** + * DragUnicodeBetweenJVMTest.java + * + * summary: The test drags a list of files (DataFlavor.javaFileListFlavor) from one jvm to another. + * The files have Unicode names. The list on target side must be equal to + * the list on the source side. + */ + + +import java.awt.*; +import java.awt.event.*; +import java.applet.Applet; + +import test.java.awt.regtesthelpers.process.ProcessCommunicator; +import test.java.awt.regtesthelpers.process.ProcessResults; +import test.java.awt.regtesthelpers.Util; +import static java.lang.Thread.sleep; + +public class DragUnicodeBetweenJVMTest extends Applet +{ + + public void init() { + setLayout(new BorderLayout()); + }//End init() + + public void start() { + + String toolkit = Toolkit.getDefaultToolkit().getClass().getName(); + if (!toolkit.equals("sun.awt.windows.WToolkit")){ + System.out.println("This test is for Windows only. Passed."); + return; + } + else{ + System.out.println("Toolkit = " + toolkit); + } + + final Frame sourceFrame = new Frame("Source frame"); + final SourcePanel sourcePanel = new SourcePanel(); + sourceFrame.add(sourcePanel); + sourceFrame.pack(); + sourceFrame.addWindowListener( new WindowAdapter() { + @Override + public void windowClosing(WindowEvent e) { + sourceFrame.dispose(); + } + }); + sourceFrame.setVisible(true); + + Util.waitForIdle(null); + + NextFramePositionCalculator positionCalculator = new NextFramePositionCalculator(sourceFrame); + + String [] args = new String [] { + String.valueOf(positionCalculator.getNextLocationX()), + String.valueOf(positionCalculator.getNextLocationY()), + String.valueOf(AbsoluteComponentCenterCalculator.calculateXCenterCoordinate(sourcePanel)), + String.valueOf(AbsoluteComponentCenterCalculator.calculateYCenterCoordinate(sourcePanel)), + }; + + + ProcessResults processResults = + // ProcessCommunicator.executeChildProcess(this.getClass()," -cp \"C:\\Documents and Settings\\df153228\\IdeaProjects\\UnicodeTestDebug\\out\\production\\UnicodeTestDebug\" -Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=5005 ", args); + ProcessCommunicator.executeChildProcess(this.getClass(), args); + + verifyTestResults(processResults); + + }// start() + + + + private static void verifyTestResults(ProcessResults processResults) { + if ( InterprocessMessages.FILES_ON_TARGET_ARE_CORRUPTED == + processResults.getExitValue()) + { + processResults.printProcessErrorOutput(System.err); + throw new RuntimeException("TEST IS FAILED: Target has recieved" + + " broken file list."); + } + processResults.verifyStdErr(System.err); + processResults.verifyProcessExitValue(System.err); + processResults.printProcessStandartOutput(System.out); + } + + //We cannot make an instance of the applet without the default constructor + public DragUnicodeBetweenJVMTest () { + super(); + } + + //We need in this constructor to pass frame position between JVMs + public DragUnicodeBetweenJVMTest (Point targetFrameLocation, Point dragSourcePoint) + throws InterruptedException + { + final Frame targetFrame = new Frame("Target frame"); + final TargetPanel targetPanel = new TargetPanel(targetFrame); + targetFrame.add(targetPanel); + targetFrame.addWindowListener( new WindowAdapter() { + @Override + public void windowClosing(WindowEvent e) { + targetFrame.dispose(); + } + }); + targetFrame.setLocation(targetFrameLocation); + targetFrame.pack(); + targetFrame.setVisible(true); + + doTest(dragSourcePoint, targetPanel); + } + + private void doTest(Point dragSourcePoint, TargetPanel targetPanel) { + Util.waitForIdle(null); + + final Robot robot = Util.createRobot(); + + robot.mouseMove((int)dragSourcePoint.getX(),(int)dragSourcePoint.getY()); + try { + sleep(100); + robot.mousePress(InputEvent.BUTTON1_MASK); + sleep(100); + robot.mouseRelease(InputEvent.BUTTON1_MASK); + sleep(100); + } catch (InterruptedException e) { + e.printStackTrace(); + } + + Util.drag(robot, dragSourcePoint, new Point (AbsoluteComponentCenterCalculator.calculateXCenterCoordinate(targetPanel), + AbsoluteComponentCenterCalculator.calculateYCenterCoordinate(targetPanel)), + InputEvent.BUTTON1_MASK); + } + + + enum InterprocessArguments { + TARGET_FRAME_X_POSITION_ARGUMENT, + TARGET_FRAME_Y_POSITION_ARGUMENT, + DRAG_SOURCE_POINT_X_ARGUMENT, + DRAG_SOURCE_POINT_Y_ARGUMENT; + + int extract (String [] args) { + return Integer.parseInt(args[this.ordinal()]); + } + } + + public static void main (String [] args) { + Point dragSourcePoint = new Point(InterprocessArguments.DRAG_SOURCE_POINT_X_ARGUMENT.extract(args), + InterprocessArguments.DRAG_SOURCE_POINT_Y_ARGUMENT.extract(args)); + Point targetFrameLocation = new Point(InterprocessArguments.TARGET_FRAME_X_POSITION_ARGUMENT.extract(args), + InterprocessArguments.TARGET_FRAME_Y_POSITION_ARGUMENT.extract(args)); + + try { + new DragUnicodeBetweenJVMTest(targetFrameLocation, dragSourcePoint); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + + +} diff -r feacdd1c5df3 -r 1411f4ebf52e jdk/test/java/awt/datatransfer/DragUnicodeBetweenJVMTest/FileListTransferable.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/java/awt/datatransfer/DragUnicodeBetweenJVMTest/FileListTransferable.java Thu Dec 10 09:46:13 2009 -0800 @@ -0,0 +1,68 @@ +/* + * Copyright 2009 Sun Microsystems, Inc. All Rights Reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +import java.awt.datatransfer.Transferable; +import java.awt.datatransfer.DataFlavor; +import java.awt.datatransfer.UnsupportedFlavorException; +import java.io.IOException; +import java.io.File; +import java.util.Arrays; +import java.util.List; + +class FileListTransferable implements Transferable { + + public static File [] files = new File [] { + new File ("\u042f\u0020\u0441\u0440\u0430\u0437\u0443\u0020\u0441\u043c\u0430\u0437\u0430\u043b" + + "\u0020\u043a\u0430\u0440\u0442\u0443\u0020\u0431\u0443\u0434\u043d\u044f"), + new File ("\u043f\u043b\u0435\u0441\u043d\u0443\u0432\u0448\u0438\u0020\u043a\u0440\u0430\u0441" + + "\u043a\u0443\u0020\u0438\u0437\u0020\u0441\u0442\u0430\u043a\u0430\u043d\u0430"), + new File ("\u044f\u0020\u043f\u043e\u043a\u0430\u0437\u0430\u043b\u0020\u043d\u0430\u0020\u0431" + + "\u043b\u044e\u0434\u0435\u0020\u0441\u0442\u0443\u0434\u043d\u044f"), + new File ("\u043a\u043e\u0441\u044b\u0435\u0020\u0441\u043a\u0443\u043b\u044b\u0020\u043e\u043a" + + "\u0435\u0430\u043d\u0430"), + new File ("\u041d\u0430\u0020\u0447\u0435\u0448\u0443\u0435\u0020\u0436\u0435\u0441\u0442\u044f" + + "\u043d\u043e\u0439\u0020\u0440\u044b\u0431\u044b"), + new File ("\u043f\u0440\u043e\u0447\u0435\u043b\u0020\u044f\u0020\u0437\u043e\u0432\u044b\u0020" + + "\u043d\u043e\u0432\u044b\u0445\u0020\u0433\u0443\u0431"), + new File ("\u0410\u0020\u0432\u044b"), + new File ("\u043d\u043e\u043a\u0442\u044e\u0440\u043d\u0020\u0441\u044b\u0433\u0440\u0430\u0442" + + "\u044c"), + new File ("\u043c\u043e\u0433\u043b\u0438\u0020\u0431\u044b"), + new File ("\u043d\u0430\u0020\u0444\u043b\u0435\u0439\u0442\u0435\u0020\u0432\u043e\u0434\u043e" + + "\u0441\u0442\u043e\u0447\u043d\u044b\u0445\u0020\u0442\u0440\u0443\u0431"), + }; + + public DataFlavor[] getTransferDataFlavors() { + return new DataFlavor [] {DataFlavor.javaFileListFlavor}; + } + + public boolean isDataFlavorSupported(DataFlavor flavor) { + return flavor.equals(DataFlavor.javaFileListFlavor) ; + } + + public Object getTransferData(DataFlavor flavor) throws UnsupportedFlavorException, IOException { + List list = Arrays.asList(files); + return list; + + } +} diff -r feacdd1c5df3 -r 1411f4ebf52e jdk/test/java/awt/datatransfer/DragUnicodeBetweenJVMTest/InterprocessMessages.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/java/awt/datatransfer/DragUnicodeBetweenJVMTest/InterprocessMessages.java Thu Dec 10 09:46:13 2009 -0800 @@ -0,0 +1,28 @@ +/* + * Copyright 2009 Sun Microsystems, Inc. All Rights Reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +interface InterprocessMessages { + final static int EXECUTION_IS_SUCCESSFULL = 0; + final static int FILES_ON_TARGET_ARE_CORRUPTED = 212; +} + diff -r feacdd1c5df3 -r 1411f4ebf52e jdk/test/java/awt/datatransfer/DragUnicodeBetweenJVMTest/NextFramePositionCalculator.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/java/awt/datatransfer/DragUnicodeBetweenJVMTest/NextFramePositionCalculator.java Thu Dec 10 09:46:13 2009 -0800 @@ -0,0 +1,43 @@ +/* + * Copyright 2009 Sun Microsystems, Inc. All Rights Reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +import java.awt.*; + + +class NextFramePositionCalculator { + + private final Frame currentFrame; + + public NextFramePositionCalculator (Frame currentFrame) { + this.currentFrame = currentFrame; + } + + public int getNextLocationX() { + return currentFrame.getX()+currentFrame.getWidth(); + } + + public int getNextLocationY() { + return currentFrame.getY(); + } + +} diff -r feacdd1c5df3 -r 1411f4ebf52e jdk/test/java/awt/datatransfer/DragUnicodeBetweenJVMTest/SourcePanel.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/java/awt/datatransfer/DragUnicodeBetweenJVMTest/SourcePanel.java Thu Dec 10 09:46:13 2009 -0800 @@ -0,0 +1,50 @@ +/* + * Copyright 2009 Sun Microsystems, Inc. All Rights Reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +import java.awt.dnd.DragSource; +import java.awt.dnd.DnDConstants; +import java.awt.dnd.DragGestureEvent; +import java.awt.dnd.DragGestureListener; +import java.awt.*; + +public class SourcePanel extends Panel +{ + + private final MyDragGestureListener dragGestureListener = + new MyDragGestureListener(); + + public SourcePanel () { + setPreferredSize(new Dimension(200, 200)); + DragSource defaultDragSource = + DragSource.getDefaultDragSource(); + defaultDragSource.createDefaultDragGestureRecognizer(this, + DnDConstants.ACTION_COPY_OR_MOVE, dragGestureListener); + setBackground(Color.RED); + } + + private class MyDragGestureListener implements DragGestureListener { + public void dragGestureRecognized(DragGestureEvent dge) { + dge.startDrag(null, new FileListTransferable()); + } + } +} diff -r feacdd1c5df3 -r 1411f4ebf52e jdk/test/java/awt/datatransfer/DragUnicodeBetweenJVMTest/TargetPanel.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/java/awt/datatransfer/DragUnicodeBetweenJVMTest/TargetPanel.java Thu Dec 10 09:46:13 2009 -0800 @@ -0,0 +1,115 @@ +/* + * Copyright 2009 Sun Microsystems, Inc. All Rights Reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +import java.awt.dnd.*; +import java.awt.*; +import java.awt.datatransfer.DataFlavor; +import java.awt.datatransfer.UnsupportedFlavorException; +import java.io.File; +import java.io.IOException; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Iterator; +import java.util.Arrays; + +public class TargetPanel extends Panel implements DropTargetListener{ + + private java.util.List content = new ArrayList(); + + //private final CustomDropTargetListener dropTargetListener = new CustomDropTargetListener(); + + private Frame frame; + + public TargetPanel (Frame frame) + { + this.frame = frame; + setBackground(Color.DARK_GRAY); + setPreferredSize(new Dimension(200, 200)); + setDropTarget(new DropTarget(this, this)); + } + + public void dragEnter(DropTargetDragEvent dtde) { + if (dtde.isDataFlavorSupported(DataFlavor.javaFileListFlavor)) { + dtde.acceptDrag(DnDConstants.ACTION_COPY_OR_MOVE); + } + } + + public void dragOver(DropTargetDragEvent dtde) { + if (dtde.isDataFlavorSupported(DataFlavor.javaFileListFlavor)) { + dtde.acceptDrag(DnDConstants.ACTION_COPY_OR_MOVE); + } + } + + public void dropActionChanged(DropTargetDragEvent dtde) { + if (dtde.isDataFlavorSupported(DataFlavor.javaFileListFlavor)) { + dtde.acceptDrag(DnDConstants.ACTION_COPY_OR_MOVE); + } + } + + public void dragExit(DropTargetEvent dte) { + + } + + public void drop(DropTargetDropEvent dtde) { + dtde.acceptDrop(DnDConstants.ACTION_COPY_OR_MOVE); + if (dtde.isDataFlavorSupported(DataFlavor.javaFileListFlavor)) { + try { + content = (java.util.List)dtde.getTransferable().getTransferData(DataFlavor.javaFileListFlavor); + repaint(); + } catch (UnsupportedFlavorException e) { + e.printStackTrace(); + } catch (IOException e) { + e.printStackTrace(); + } + dtde.dropComplete(true); + + + + boolean listsAreEqual = true; + + for (int i = 0; i < content.size(); i++) { + if(!FileListTransferable.files[i].getName().equals(content.get(i).getName())) { + listsAreEqual = false; + } + } + + if (listsAreEqual) { + System.err.println(InterprocessMessages.EXECUTION_IS_SUCCESSFULL); + System.exit(0); + } + } + dtde.rejectDrop(); + System.err.println(InterprocessMessages.FILES_ON_TARGET_ARE_CORRUPTED); + System.exit(1); + } + + public void paint(Graphics g) { + g.setColor(Color.YELLOW); + int i = 0; + for (Iterator iterator = content.iterator(); iterator.hasNext();i++) { + g.drawString(iterator.next().getName(), 5, g.getFontMetrics().getAscent()*i+20); + } + + } + +} diff -r feacdd1c5df3 -r 1411f4ebf52e jdk/test/java/awt/dnd/URIListBetweenJVMsTest/FileListTransferable.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/java/awt/dnd/URIListBetweenJVMsTest/FileListTransferable.java Thu Dec 10 09:46:13 2009 -0800 @@ -0,0 +1,58 @@ +/* + * Copyright 2009 Sun Microsystems, Inc. All Rights Reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +import java.awt.datatransfer.Transferable; +import java.awt.datatransfer.DataFlavor; +import java.awt.datatransfer.UnsupportedFlavorException; +import java.io.File; +import java.io.IOException; + +class FileListTransferable implements Transferable { + + final private DataFlavor[] supportedFlavors = + {DataFlavor.javaFileListFlavor}; + + private java.util.List list; + + public FileListTransferable(java.util.List list) { + this.list = list; + } + + public DataFlavor[] getTransferDataFlavors() { + return supportedFlavors; + } + + public boolean isDataFlavorSupported(DataFlavor flavor) { + for (DataFlavor df:supportedFlavors) { + if (df.equals(flavor)) return true; + } + return false; + } + + public Object getTransferData(DataFlavor flavor) throws UnsupportedFlavorException, IOException { + if (flavor.equals(DataFlavor.javaFileListFlavor)) { + return list; + } + throw new UnsupportedFlavorException(flavor); + } +} diff -r feacdd1c5df3 -r 1411f4ebf52e jdk/test/java/awt/dnd/URIListBetweenJVMsTest/InterprocessMessages.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/java/awt/dnd/URIListBetweenJVMsTest/InterprocessMessages.java Thu Dec 10 09:46:13 2009 -0800 @@ -0,0 +1,27 @@ +/* + * Copyright 2009 Sun Microsystems, Inc. All Rights Reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +public interface InterprocessMessages { + final static int EXECUTION_IS_SUCCESSFULL = 0; + final static int WRONG_FILES_NUMBER_ON_TARGET = 212; +} diff -r feacdd1c5df3 -r 1411f4ebf52e jdk/test/java/awt/dnd/URIListBetweenJVMsTest/SourceFileListFrame.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/java/awt/dnd/URIListBetweenJVMsTest/SourceFileListFrame.java Thu Dec 10 09:46:13 2009 -0800 @@ -0,0 +1,97 @@ +/* + * Copyright 2009 Sun Microsystems, Inc. All Rights Reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +import test.java.awt.regtesthelpers.Util; + +import java.awt.*; +import java.awt.dnd.DragGestureListener; +import java.awt.dnd.DragSource; +import java.awt.dnd.DnDConstants; +import java.awt.dnd.DragGestureEvent; +import java.io.File; +import java.util.Arrays; + + +class SourceFileListFrame extends Frame implements DragGestureListener { + + private final static int SOURCE_POINT_SHIFT = 3; + + private List list = new List(URIListBetweenJVMsTest.VISIBLE_RAWS_IN_LIST); + private File[] files; + + SourceFileListFrame() { + super("Source File List Frame"); + extractFilesFromTheWorkingDirectory(); + initList(); + initGUI(); + new DragSource().createDefaultDragGestureRecognizer(list, + DnDConstants.ACTION_COPY,this); + } + + private void extractFilesFromTheWorkingDirectory() { + files = new File(System.getProperty("java.home", "")).listFiles(); + } + + private void initList() { + for (File currFile:files) { + list.add(currFile.getName()); + } + } + + private void initGUI() { + this.addWindowListener(Util.getClosingWindowAdapter()); + this.setLocation(300,250); + this.add(new Panel().add(list)); + this.pack(); + this.setVisible(true); + } + + int getNextLocationX() { + return getX()+getWidth(); + } + + int getNextLocationY() { + return getY(); + } + + int getDragSourcePointX() { + return (int)list.getLocationOnScreen().getX()+(list.getWidth()/2); + } + + int getDragSourcePointY() { + return (int)list.getLocationOnScreen().getY()+ SOURCE_POINT_SHIFT; + } + + int getSourceFilesNumber() { + return files.length; + } + + public void dragGestureRecognized(DragGestureEvent dge) { + String [] filesAsStringArray = list.getItems(); + File [] files = new File[filesAsStringArray.length]; + for (int fileNumber=0; fileNumber fileList = extractListOfFiles(dtde); + for (File file:fileList) { + list.add(file.getName()); + } + + if (fileList.size() != expectationTransferredFilesNumber) + { + System.err.println("ERROR: Expected file number:" + + expectationTransferredFilesNumber + + "; Received file number: " + + fileList.size()); + TargetFileListFrame.this.dispose(); + System.exit(InterprocessMessages.WRONG_FILES_NUMBER_ON_TARGET); + } + + TargetFileListFrame.this.dispose(); + + } + + private java.util.List extractListOfFiles(DropTargetDropEvent dtde) { + BufferedReader reader = null; + ArrayList files = new ArrayList(); + try { + reader = new BufferedReader((Reader)dtde.getTransferable(). + getTransferData(dropFlavor)); + String line; + while ((line = reader.readLine()) != null) { + files.add(new File(new URI(line))); + } + } catch (UnsupportedFlavorException e) { + e.printStackTrace(); + } catch (IOException e) { + e.printStackTrace(); + } catch (IllegalArgumentException e) { + e.printStackTrace(); + } catch (URISyntaxException e) { + e.printStackTrace(); + } finally { + if (reader != null) { + try { + reader.close(); + } catch (IOException ignored) { + } + } + } + return files; + } + + Point getDropTargetPoint() { + return new Point((int)list.getLocationOnScreen().getX()+(list.getWidth()/2), + (int)list.getLocationOnScreen().getY()+(list.getHeight()/2)); + } +} diff -r feacdd1c5df3 -r 1411f4ebf52e jdk/test/java/awt/dnd/URIListBetweenJVMsTest/URIListBetweenJVMsTest.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/java/awt/dnd/URIListBetweenJVMsTest/URIListBetweenJVMsTest.html Thu Dec 10 09:46:13 2009 -0800 @@ -0,0 +1,25 @@ + + + + DnD of URI-List across JVM + + + +

URIListBetweenJVMsTest
Bug ID: 4899516

+ +

This is an AUTOMATIC test, simply wait for completion

+ + + + diff -r feacdd1c5df3 -r 1411f4ebf52e jdk/test/java/awt/dnd/URIListBetweenJVMsTest/URIListBetweenJVMsTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/java/awt/dnd/URIListBetweenJVMsTest/URIListBetweenJVMsTest.java Thu Dec 10 09:46:13 2009 -0800 @@ -0,0 +1,158 @@ +/* + * Copyright 2009 Sun Microsystems, Inc. All Rights Reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +/* + test + @bug 4899516 + @summary Transferable has no DataFlavors when dragging from Gnome window to Swing + @author : area=dnd + @run applet URIListBetweenJVMsTest.html +*/ + +/** + * URIListBetweenJVMsTest.java + * + * summary: Transferable has no DataFlavors when dragging from Gnome window to Swing + */ + +import static java.lang.Thread.sleep; + +import test.java.awt.regtesthelpers.process.ProcessCommunicator; +import test.java.awt.regtesthelpers.process.ProcessResults; +import test.java.awt.regtesthelpers.Util; +import java.applet.Applet; +import java.awt.*; +import java.awt.event.InputEvent; +import java.io.*; + +public class URIListBetweenJVMsTest extends Applet { + + // information related to the test in common + static int VISIBLE_RAWS_IN_LIST=15; + + public void init() { + setLayout(new BorderLayout()); + + }//End init() + + public void start() { + + String toolkit = Toolkit.getDefaultToolkit().getClass().getName(); + if (toolkit.equals("sun.awt.windows.WToolkit")){ + System.out.println("This test is not for the Windows platform. Passed."); + return; + } else { + System.out.println("Toolkit = " + toolkit); + } + + SourceFileListFrame sourceFrame = new SourceFileListFrame(); + + Util.waitForIdle(null); + + String [] args = new String [] { + String.valueOf(sourceFrame.getNextLocationX()), + String.valueOf(sourceFrame.getNextLocationY()), + String.valueOf(sourceFrame.getDragSourcePointX()), + String.valueOf(sourceFrame.getDragSourcePointY()), + String.valueOf(sourceFrame.getSourceFilesNumber()) + }; + + String classpath = System.getProperty("java.class.path"); + ProcessResults processResults = + ProcessCommunicator.executeChildProcess(this.getClass(), classpath, args); + + verifyTestResults(processResults); + + }// start() + + private static void verifyTestResults(ProcessResults processResults) { + if ( InterprocessMessages.WRONG_FILES_NUMBER_ON_TARGET == + processResults.getExitValue()) + { + processResults.printProcessErrorOutput(System.err); + throw new RuntimeException("TEST IS FAILED: Target has recieved" + + " wrong number of files."); + } + processResults.verifyStdErr(System.err); + processResults.verifyProcessExitValue(System.err); + processResults.printProcessStandartOutput(System.out); + } + + //We cannot make an instance of the applet without the default constructor + public URIListBetweenJVMsTest () { + super(); + } + + //We need in this constructor to pass frame position between JVMs + public URIListBetweenJVMsTest (Point targetFrameLocation, Point dragSourcePoint, + int transferredFilesNumber) + throws InterruptedException + { + TargetFileListFrame targetFrame = new TargetFileListFrame(targetFrameLocation, + transferredFilesNumber); + + Util.waitForIdle(null); + + final Robot robot = Util.createRobot(); + + robot.mouseMove((int)dragSourcePoint.getX(),(int)dragSourcePoint.getY()); + sleep(100); + robot.mousePress(InputEvent.BUTTON1_MASK); + sleep(100); + robot.mouseRelease(InputEvent.BUTTON1_MASK); + sleep(100); + + Util.drag(robot, dragSourcePoint, targetFrame.getDropTargetPoint(), + InputEvent.BUTTON1_MASK); + + } + + enum InterprocessArguments { + TARGET_FRAME_X_POSITION_ARGUMENT, + TARGET_FRAME_Y_POSITION_ARGUMENT, + DRAG_SOURCE_POINT_X_ARGUMENT, + DRAG_SOURCE_POINT_Y_ARGUMENT, + FILES_IN_THE_LIST_NUMBER_ARGUMENT; + + int extract (String [] args) { + return Integer.parseInt(args[this.ordinal()]); + } + } + + public static void main (String [] args) { + Point dragSourcePoint = new Point(InterprocessArguments.DRAG_SOURCE_POINT_X_ARGUMENT.extract(args), + InterprocessArguments.DRAG_SOURCE_POINT_Y_ARGUMENT.extract(args)); + Point targetFrameLocation = new Point(InterprocessArguments.TARGET_FRAME_X_POSITION_ARGUMENT.extract(args), + InterprocessArguments.TARGET_FRAME_Y_POSITION_ARGUMENT.extract(args)); + int transferredFilesNumber = InterprocessArguments.FILES_IN_THE_LIST_NUMBER_ARGUMENT.extract(args); + + try { + new URIListBetweenJVMsTest(targetFrameLocation, dragSourcePoint, transferredFilesNumber); + } catch (InterruptedException e) { + e.printStackTrace(); + } + + } + + +}// class URIListBetweenJVMsTest diff -r feacdd1c5df3 -r 1411f4ebf52e jdk/test/java/awt/regtesthelpers/process/ProcessCommunicator.java --- a/jdk/test/java/awt/regtesthelpers/process/ProcessCommunicator.java Thu Dec 10 09:43:48 2009 -0800 +++ b/jdk/test/java/awt/regtesthelpers/process/ProcessCommunicator.java Thu Dec 10 09:46:13 2009 -0800 @@ -146,7 +146,15 @@ final String classPathArguments, final String [] args) { StringBuilder commandBuilder = new StringBuilder(); - commandBuilder.append(javaPath).append(classPathArguments).append(classToExecute.getName()); + commandBuilder.append(javaPath).append(" "); + commandBuilder.append("-cp ").append(System.getProperty("test.classes", ".")).append(File.pathSeparatorChar); + + if (classPathArguments.trim().length() > 0) { + commandBuilder.append(classPathArguments).append(" "); + } + + commandBuilder.append(" "); + commandBuilder.append(classToExecute.getName()); for (String argument:args) { commandBuilder.append(" ").append(argument); }