--- a/jdk/src/java.desktop/macosx/classes/com/apple/laf/AquaIcon.java Tue Oct 28 11:29:59 2014 -0400
+++ b/jdk/src/java.desktop/macosx/classes/com/apple/laf/AquaIcon.java Tue Oct 28 17:17:05 2014 -0400
@@ -62,7 +62,7 @@
if (w <= 0 || h <= 0) return null;
// This could be any kind of icon, so we need to make a buffer for it, draw it and then pass the new image off to appkit.
- final BufferedImage image = new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB);
+ final BufferedImage image = new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB_PRE);
final Graphics g = image.getGraphics();
i.paintIcon(null, g, 0, 0);
g.dispose();
--- a/jdk/src/java.desktop/macosx/classes/com/apple/laf/AquaImageFactory.java Tue Oct 28 11:29:59 2014 -0400
+++ b/jdk/src/java.desktop/macosx/classes/com/apple/laf/AquaImageFactory.java Tue Oct 28 17:17:05 2014 -0400
@@ -129,7 +129,7 @@
};
final BufferedImage image = new BufferedImage(scaledAlertIconSize,
- scaledAlertIconSize, BufferedImage.TYPE_INT_ARGB);
+ scaledAlertIconSize, BufferedImage.TYPE_INT_ARGB_PRE);
final Graphics g = image.getGraphics();
g.drawImage(background, 0, 0,
scaledAlertIconSize, scaledAlertIconSize, null);
--- a/jdk/src/java.desktop/macosx/classes/com/apple/laf/AquaNativeResources.java Tue Oct 28 11:29:59 2014 -0400
+++ b/jdk/src/java.desktop/macosx/classes/com/apple/laf/AquaNativeResources.java Tue Oct 28 17:17:05 2014 -0400
@@ -67,11 +67,12 @@
}
static BufferedImage getRadioButtonSizerImage() {
- final BufferedImage img = new BufferedImage(20, 20, BufferedImage.TYPE_INT_ARGB);
+ final BufferedImage img = new BufferedImage(20, 20, BufferedImage.TYPE_INT_ARGB_PRE);
Graphics g = img.getGraphics();
g.setColor(Color.pink);
g.fillRect(0, 0, 20, 20);
+ g.dispose();
return img;
}
--- a/jdk/src/java.desktop/macosx/classes/sun/lwawt/macosx/CPlatformWindow.java Tue Oct 28 11:29:59 2014 -0400
+++ b/jdk/src/java.desktop/macosx/classes/sun/lwawt/macosx/CPlatformWindow.java Tue Oct 28 17:17:05 2014 -0400
@@ -676,6 +676,13 @@
@Override // PlatformWindow
public void toFront() {
final long nsWindowPtr = getNSWindowPtr();
+ LWCToolkit lwcToolkit = (LWCToolkit) Toolkit.getDefaultToolkit();
+ Window w = DefaultKeyboardFocusManager.getCurrentKeyboardFocusManager().getActiveWindow();
+ if( w != null
+ && ((LWWindowPeer)w.getPeer()).getPeerType() == LWWindowPeer.PeerType.EMBEDDED_FRAME
+ && !lwcToolkit.isApplicationActive()) {
+ lwcToolkit.activateApplicationIgnoringOtherApps();
+ }
updateFocusabilityForAutoRequestFocus(false);
nativePushNSWindowToFront(nsWindowPtr);
updateFocusabilityForAutoRequestFocus(true);
--- a/jdk/src/java.desktop/macosx/classes/sun/lwawt/macosx/LWCToolkit.java Tue Oct 28 11:29:59 2014 -0400
+++ b/jdk/src/java.desktop/macosx/classes/sun/lwawt/macosx/LWCToolkit.java Tue Oct 28 17:17:05 2014 -0400
@@ -811,6 +811,11 @@
*/
public static native boolean isEmbedded();
+ /*
+ * Activates application ignoring other apps.
+ */
+ public native void activateApplicationIgnoringOtherApps();
+
/************************
* Native methods section
************************/
--- a/jdk/src/java.desktop/macosx/native/libawt_lwawt/awt/LWCToolkit.m Tue Oct 28 11:29:59 2014 -0400
+++ b/jdk/src/java.desktop/macosx/native/libawt_lwawt/awt/LWCToolkit.m Tue Oct 28 17:17:05 2014 -0400
@@ -606,6 +606,23 @@
return active;
}
+/*
+ * Class: sun_lwawt_macosx_LWCToolkit
+ * Method: activateApplicationIgnoringOtherApps
+ * Signature: ()V
+ */
+JNIEXPORT void JNICALL Java_sun_lwawt_macosx_LWCToolkit_activateApplicationIgnoringOtherApps
+(JNIEnv *env, jclass clazz)
+{
+ JNF_COCOA_ENTER(env);
+ [ThreadUtilities performOnMainThreadWaiting:NO block:^(){
+ if(![NSApp isActive]){
+ [NSApp activateIgnoringOtherApps:YES];
+ }
+ }];
+ JNF_COCOA_EXIT(env);
+}
+
/*
* Class: sun_awt_SunToolkit
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.desktop/share/classes/META-INF/services/javax.print.PrintServiceLookup Tue Oct 28 17:17:05 2014 -0400
@@ -0,0 +1,2 @@
+# Provider for Java Print Service
+sun.print.PrintServiceLookupProvider
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.desktop/share/classes/META-INF/services/javax.print.StreamPrintServiceFactory Tue Oct 28 17:17:05 2014 -0400
@@ -0,0 +1,2 @@
+# Provider for Java 2D Stream print services.
+sun.print.PSStreamPrinterFactory
--- a/jdk/src/java.desktop/share/classes/java/awt/Container.java Tue Oct 28 11:29:59 2014 -0400
+++ b/jdk/src/java.desktop/share/classes/java/awt/Container.java Tue Oct 28 17:17:05 2014 -0400
@@ -3696,7 +3696,7 @@
private void writeObject(ObjectOutputStream s) throws IOException {
ObjectOutputStream.PutField f = s.putFields();
f.put("ncomponents", component.size());
- f.put("component", getComponentsSync());
+ f.put("component", component.toArray(EMPTY_ARRAY));
f.put("layoutMgr", layoutMgr);
f.put("dispatcher", dispatcher);
f.put("maxSize", maxSize);
--- a/jdk/src/java.desktop/share/classes/java/awt/color/ICC_Profile.java Tue Oct 28 11:29:59 2014 -0400
+++ b/jdk/src/java.desktop/share/classes/java/awt/color/ICC_Profile.java Tue Oct 28 17:17:05 2014 -0400
@@ -48,6 +48,7 @@
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
+import java.io.FilePermission;
import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectInputStream;
@@ -1857,7 +1858,13 @@
* returns null.
*/
private static InputStream getStandardProfileInputStream(String fileName) {
- return PCMM.class.getResourceAsStream("profiles/" + fileName);
+ return AccessController.doPrivileged(
+ new PrivilegedAction<InputStream>() {
+ public InputStream run () {
+ return
+ PCMM.class.getResourceAsStream("profiles/" + fileName);
+ }
+ }, null, new FilePermission("<<ALL FILES>>", "read"));
}
/**
--- a/jdk/src/java.desktop/share/classes/javax/swing/BorderFactory.java Tue Oct 28 11:29:59 2014 -0400
+++ b/jdk/src/java.desktop/share/classes/javax/swing/BorderFactory.java Tue Oct 28 17:17:05 2014 -0400
@@ -35,7 +35,7 @@
* possible, this factory will hand out references to shared
* <code>Border</code> instances.
* For further information and examples see
- * <a href="http://docs.oracle.com/javase/tutorial/uiswing/components/border.htmll">How
+ * <a href="http://docs.oracle.com/javase/tutorial/uiswing/components/border.html">How
to Use Borders</a>,
* a section in <em>The Java Tutorial</em>.
*
--- a/jdk/src/java.desktop/share/classes/javax/swing/JComponent.java Tue Oct 28 11:29:59 2014 -0400
+++ b/jdk/src/java.desktop/share/classes/javax/swing/JComponent.java Tue Oct 28 17:17:05 2014 -0400
@@ -126,7 +126,7 @@
* that includes double buffering and support for borders.
* For more information see <a
* href="http://www.oracle.com/technetwork/java/painting-140037.html#swing">Painting</a> and
- * <a href="http://docs.oracle.com/javase/tutorial/uiswing/components/border.htmll">How
+ * <a href="http://docs.oracle.com/javase/tutorial/uiswing/components/border.html">How
* to Use Borders</a>,
* both of which are sections in <em>The Java Tutorial</em>.
* </ul>
--- a/jdk/src/java.desktop/share/classes/javax/swing/JInternalFrame.java Tue Oct 28 11:29:59 2014 -0400
+++ b/jdk/src/java.desktop/share/classes/javax/swing/JInternalFrame.java Tue Oct 28 17:17:05 2014 -0400
@@ -1141,14 +1141,15 @@
/**
* Sets an image to be displayed in the titlebar of this internal frame (usually
* in the top-left corner).
+ * Some look and feels might not support displaying an icon in the titlebar.
+ *
* This image is not the <code>desktopIcon</code> object, which
* is the image displayed in the <code>JDesktop</code> when
* this internal frame is iconified.
*
* Passing <code>null</code> to this function is valid,
- * but the look and feel
- * can choose the
- * appropriate behavior for that situation, such as displaying no icon
+ * but the look and feel can choose the appropriate behavior
+ * for that situation, such as displaying no icon
* or a default icon for the look and feel.
*
* @param icon the <code>Icon</code> to display in the title bar
--- a/jdk/src/java.desktop/share/classes/javax/swing/JLayer.java Tue Oct 28 11:29:59 2014 -0400
+++ b/jdk/src/java.desktop/share/classes/javax/swing/JLayer.java Tue Oct 28 17:17:05 2014 -0400
@@ -325,24 +325,38 @@
}
/**
- * A non-{@code null} border, or non-zero insets, isn't supported, to prevent the geometry
- * of this component from becoming complex enough to inhibit
- * subclassing of {@code LayerUI} class. To create a {@code JLayer} with a border,
- * add it to a {@code JPanel} that has a border.
- * <p>Note: If {@code border} is non-{@code null}, this
- * method will throw an exception as borders are not supported on
- * a {@code JLayer}.
+ * Delegates its functionality to the {@code getView().setBorder(Border)} method,
+ * if the view component is an instance of {@code javax.swing.JComponent},
+ * otherwise this method is a no-op.
*
- * @param border the {@code Border} to set
- * @exception IllegalArgumentException this method is not supported
+ * @param border the border to be rendered for the {@code view} component
+ * @see #getView()
+ * @see javax.swing.JComponent#setBorder(Border)
*/
public void setBorder(Border border) {
- if (border != null) {
- throw new IllegalArgumentException("JLayer.setBorder() not supported");
+ if (view instanceof JComponent) {
+ ((JComponent)view).setBorder(border);
}
}
/**
+ * Delegates its functionality to the {@code getView().getBorder()} method,
+ * if the view component is an instance of {@code javax.swing.JComponent},
+ * otherwise returns {@code null}.
+ *
+ * @return the border object for the {@code view} component
+ * @see #getView()
+ * @see #setBorder
+ * @see javax.swing.JComponent#getBorder()
+ */
+ public Border getBorder() {
+ if (view instanceof JComponent) {
+ return ((JComponent) view).getBorder();
+ }
+ return null;
+ }
+
+ /**
* This method is not supported by {@code JLayer}
* and always throws {@code UnsupportedOperationException}
*
--- a/jdk/src/java.desktop/share/classes/javax/swing/border/Border.java Tue Oct 28 11:29:59 2014 -0400
+++ b/jdk/src/java.desktop/share/classes/javax/swing/border/Border.java Tue Oct 28 17:17:05 2014 -0400
@@ -33,7 +33,7 @@
* Interface describing an object capable of rendering a border
* around the edges of a swing component.
* For examples of using borders see
- * <a href="http://docs.oracle.com/javase/tutorial/uiswing/components/border.htmll">How to Use Borders</a>,
+ * <a href="http://docs.oracle.com/javase/tutorial/uiswing/components/border.html">How to Use Borders</a>,
* a section in <em>The Java Tutorial.</em>
* <p>
* In the Swing component set, borders supercede Insets as the
--- a/jdk/src/java.desktop/share/classes/javax/swing/border/package.html Tue Oct 28 11:29:59 2014 -0400
+++ b/jdk/src/java.desktop/share/classes/javax/swing/border/package.html Tue Oct 28 17:17:05 2014 -0400
@@ -40,10 +40,10 @@
Most of the Swing API is <em>not</em> thread safe.
For details, see
<a
-href="http://java.sun.com/docs/books/tutorial/uiswing/overview/threads.html"
-target="_top">Threads and Swing</a>,
+href="http://docs.oracle.com/javase/tutorial/uiswing/concurrency/index.html"
+target="_top">Concurrency in Swing</a>,
a section in
-<em><a href="http://java.sun.com/docs/books/tutorial/"
+<em><a href="http://docs.oracle.com/javase/tutorial/"
target="_top">The Java Tutorial</a></em>.
@@ -51,7 +51,7 @@
For overviews, tutorials, examples, guides, and tool documentation, please see:
<ul>
- <li><a href="http://java.sun.com/docs/books/tutorial/uiswing/misc/border.html"
+ <li><a href="http://docs.oracle.com/javase/tutorial/uiswing/components/border.html"
target="_top">How to Use Borders</a>,
a section in <em>The Java Tutorial</em>
</ul>
--- a/jdk/src/java.desktop/share/classes/javax/swing/plaf/basic/BasicRadioButtonUI.java Tue Oct 28 11:29:59 2014 -0400
+++ b/jdk/src/java.desktop/share/classes/javax/swing/plaf/basic/BasicRadioButtonUI.java Tue Oct 28 17:17:05 2014 -0400
@@ -33,7 +33,8 @@
import javax.swing.text.View;
import sun.swing.SwingUtilities2;
import sun.awt.AppContext;
-
+import java.util.Enumeration;
+import java.util.HashSet;
/**
* RadioButtonUI implementation for BasicRadioButtonUI
@@ -53,6 +54,8 @@
private final static String propertyPrefix = "RadioButton" + ".";
+ private KeyListener keyListener = null;
+
// ********************************
// Create PLAF
// ********************************
@@ -74,6 +77,7 @@
return radioButtonUI;
}
+ @Override
protected String getPropertyPrefix() {
return propertyPrefix;
}
@@ -81,7 +85,8 @@
// ********************************
// Install PLAF
// ********************************
- protected void installDefaults(AbstractButton b){
+ @Override
+ protected void installDefaults(AbstractButton b) {
super.installDefaults(b);
if(!defaults_initialized) {
icon = UIManager.getIcon(getPropertyPrefix() + "icon");
@@ -92,7 +97,8 @@
// ********************************
// Uninstall PLAF
// ********************************
- protected void uninstallDefaults(AbstractButton b){
+ @Override
+ protected void uninstallDefaults(AbstractButton b) {
super.uninstallDefaults(b);
defaults_initialized = false;
}
@@ -106,6 +112,65 @@
return icon;
}
+ // ********************************
+ // Install Listeners
+ // ********************************
+ @Override
+ protected void installListeners(AbstractButton button) {
+ super.installListeners(button);
+
+ // Only for JRadioButton
+ if (!(button instanceof JRadioButton))
+ return;
+
+ keyListener = createKeyListener();
+ button.addKeyListener(keyListener);
+
+ // Need to get traversal key event
+ button.setFocusTraversalKeysEnabled(false);
+
+ // Map actions to the arrow keys
+ button.getActionMap().put("Previous", new SelectPreviousBtn());
+ button.getActionMap().put("Next", new SelectNextBtn());
+
+ button.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT).
+ put(KeyStroke.getKeyStroke("UP"), "Previous");
+ button.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT).
+ put(KeyStroke.getKeyStroke("DOWN"), "Next");
+ button.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT).
+ put(KeyStroke.getKeyStroke("LEFT"), "Previous");
+ button.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT).
+ put(KeyStroke.getKeyStroke("RIGHT"), "Next");
+ }
+
+ // ********************************
+ // UnInstall Listeners
+ // ********************************
+ @Override
+ protected void uninstallListeners(AbstractButton button) {
+ super.uninstallListeners(button);
+
+ // Only for JRadioButton
+ if (!(button instanceof JRadioButton))
+ return;
+
+ // Unmap actions from the arrow keys
+ button.getActionMap().remove("Previous");
+ button.getActionMap().remove("Next");
+ button.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT)
+ .remove(KeyStroke.getKeyStroke("UP"));
+ button.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT)
+ .remove(KeyStroke.getKeyStroke("DOWN"));
+ button.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT)
+ .remove(KeyStroke.getKeyStroke("LEFT"));
+ button.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT)
+ .remove(KeyStroke.getKeyStroke("RIGHT"));
+
+ if (keyListener != null) {
+ button.removeKeyListener(keyListener);
+ keyListener = null;
+ }
+ }
/* These Dimensions/Rectangles are allocated once for all
* RadioButtonUI.paint() calls. Re-using rectangles
@@ -121,6 +186,7 @@
/**
* paint the radio button
*/
+ @Override
public synchronized void paint(Graphics g, JComponent c) {
AbstractButton b = (AbstractButton) c;
ButtonModel model = b.getModel();
@@ -217,7 +283,7 @@
* @param textRect bounds
* @param size the size of radio button
*/
- protected void paintFocus(Graphics g, Rectangle textRect, Dimension size){
+ protected void paintFocus(Graphics g, Rectangle textRect, Dimension size) {
}
@@ -235,6 +301,7 @@
/**
* The preferred size of the radio button
*/
+ @Override
public Dimension getPreferredSize(JComponent c) {
if(c.getComponentCount() > 0) {
return null;
@@ -280,4 +347,262 @@
height += prefInsets.top + prefInsets.bottom;
return new Dimension(width, height);
}
+
+ /////////////////////////// Private functions ////////////////////////
+ /**
+ * Creates the key listener to handle tab navigation in JRadioButton Group.
+ */
+ private KeyListener createKeyListener() {
+ if (keyListener == null) {
+ keyListener = new KeyHandler();
+ }
+ return keyListener;
+ }
+
+
+ private boolean isValidRadioButtonObj(Object obj) {
+ return ((obj instanceof JRadioButton) &&
+ ((JRadioButton) obj).isVisible() &&
+ ((JRadioButton) obj).isEnabled());
+ }
+
+ /**
+ * Select radio button based on "Previous" or "Next" operation
+ *
+ * @param event, the event object.
+ * @param next, indicate if it's next one
+ */
+ private void selectRadioButton(ActionEvent event, boolean next) {
+ // Get the source of the event.
+ Object eventSrc = event.getSource();
+
+ // Check whether the source is JRadioButton, it so, whether it is visible
+ if (!isValidRadioButtonObj(eventSrc))
+ return;
+
+ ButtonGroupInfo btnGroupInfo = new ButtonGroupInfo((JRadioButton)eventSrc);
+ btnGroupInfo.selectNewButton(next);
+ }
+
+ /////////////////////////// Inner Classes ////////////////////////
+ @SuppressWarnings("serial")
+ private class SelectPreviousBtn extends AbstractAction {
+ public SelectPreviousBtn() {
+ super("Previous");
+ }
+
+ public void actionPerformed(ActionEvent e) {
+ BasicRadioButtonUI.this.selectRadioButton(e, false);
+ }
+ }
+
+ @SuppressWarnings("serial")
+ private class SelectNextBtn extends AbstractAction{
+ public SelectNextBtn() {
+ super("Next");
+ }
+
+ public void actionPerformed(ActionEvent e) {
+ BasicRadioButtonUI.this.selectRadioButton(e, true);
+ }
+ }
+
+ /**
+ * ButtonGroupInfo, used to get related info in button group
+ * for given radio button
+ */
+ private class ButtonGroupInfo {
+
+ JRadioButton activeBtn = null;
+
+ JRadioButton firstBtn = null;
+ JRadioButton lastBtn = null;
+
+ JRadioButton previousBtn = null;
+ JRadioButton nextBtn = null;
+
+ HashSet<JRadioButton> btnsInGroup = null;
+
+ boolean srcFound = false;
+ public ButtonGroupInfo(JRadioButton btn) {
+ activeBtn = btn;
+ btnsInGroup = new HashSet<JRadioButton>();
+ }
+
+ // Check if given object is in the button group
+ boolean containsInGroup(Object obj){
+ return btnsInGroup.contains(obj);
+ }
+
+ // Check if the next object to gain focus belongs
+ // to the button group or not
+ Component getFocusTransferBaseComponent(boolean next){
+ Component focusBaseComp = activeBtn;
+ Window container = SwingUtilities.getWindowAncestor(activeBtn);
+ if (container != null) {
+ FocusTraversalPolicy policy = container.getFocusTraversalPolicy();
+ Component comp = next ? policy.getComponentAfter(container, activeBtn)
+ : policy.getComponentBefore(container, activeBtn);
+
+ // If next component in the button group, use last/first button as base focus
+ // otherwise, use the activeBtn as the base focus
+ if (containsInGroup(comp)) {
+ focusBaseComp = next ? lastBtn : firstBtn;
+ }
+ }
+
+ return focusBaseComp;
+ }
+
+ boolean getButtonGroupInfo() {
+ if (activeBtn == null)
+ return false;
+
+ btnsInGroup.clear();
+
+ // Get the button model from the source.
+ ButtonModel model = activeBtn.getModel();
+ if (!(model instanceof DefaultButtonModel))
+ return false;
+
+ // If the button model is DefaultButtonModel, and use it, otherwise return.
+ DefaultButtonModel bm = (DefaultButtonModel) model;
+
+ // get the ButtonGroup of the button from the button model
+ ButtonGroup group = bm.getGroup();
+ if (group == null)
+ return false;
+
+ // Get all the buttons in the group
+ Enumeration<AbstractButton> e = group.getElements();
+ if (e == null)
+ return false;
+
+ while (e.hasMoreElements()) {
+ AbstractButton curElement = e.nextElement();
+ if (!isValidRadioButtonObj(curElement))
+ continue;
+
+ btnsInGroup.add((JRadioButton) curElement);
+
+ // If firstBtn is not set yet, curElement is that first button
+ if (null == firstBtn)
+ firstBtn = (JRadioButton) curElement;
+
+ if (activeBtn == curElement)
+ srcFound = true;
+ else if (!srcFound) {
+ // The source has not been yet found and the current element
+ // is the last previousBtn
+ previousBtn = (JRadioButton) curElement;
+ } else if (nextBtn == null) {
+ // The source has been found and the current element
+ // is the next valid button of the list
+ nextBtn = (JRadioButton) curElement;
+ }
+
+ // Set new last "valid" JRadioButton of the list
+ lastBtn = (JRadioButton) curElement;
+ }
+
+ return true;
+ }
+
+ /**
+ * Find the new radio button that focus needs to be
+ * moved to in the group, select the button
+ *
+ * @param next, indicate if it's arrow up/left or down/right
+ */
+ void selectNewButton(boolean next) {
+ if (!getButtonGroupInfo())
+ return;
+
+ if (srcFound) {
+ JRadioButton newSelectedBtn = null;
+ if (next) {
+ // Select Next button. Cycle to the first button if the source
+ // button is the last of the group.
+ newSelectedBtn = (null == nextBtn) ? firstBtn : nextBtn;
+ } else {
+ // Select previous button. Cycle to the last button if the source
+ // button is the first button of the group.
+ newSelectedBtn = (null == previousBtn) ? lastBtn : previousBtn;
+ }
+ if (newSelectedBtn != null &&
+ (newSelectedBtn != activeBtn)) {
+ newSelectedBtn.requestFocusInWindow();
+ newSelectedBtn.setSelected(true);
+ }
+ }
+ }
+
+ /**
+ * Find the button group the passed in JRadioButton belongs to, and
+ * move focus to next component of the last button in the group
+ * or previous component of first button
+ *
+ * @param next, indicate if jump to next component or previous
+ */
+ void jumpToNextComponent(boolean next) {
+ if (!getButtonGroupInfo()){
+ // In case the button does not belong to any group, it needs
+ // to be treated as a component
+ if (activeBtn != null){
+ lastBtn = activeBtn;
+ firstBtn = activeBtn;
+ }
+ else
+ return;
+ }
+
+ // Update the component we will use as base to transfer
+ // focus from
+ JComponent compTransferFocusFrom = activeBtn;
+
+ // If next component in the parent window is not in
+ // the button group, current active button will be
+ // base, otherwise, the base will be first or last
+ // button in the button group
+ Component focusBase = getFocusTransferBaseComponent(next);
+ if (focusBase != null){
+ if (next) {
+ KeyboardFocusManager.
+ getCurrentKeyboardFocusManager().focusNextComponent(focusBase);
+ } else {
+ KeyboardFocusManager.
+ getCurrentKeyboardFocusManager().focusPreviousComponent(focusBase);
+ }
+ }
+ }
+ }
+
+ /**
+ * Radiobutton KeyListener
+ */
+ private class KeyHandler implements KeyListener {
+
+ // This listener checks if the key event is a KeyEvent.VK_TAB
+ // or shift + KeyEvent.VK_TAB event on a radio button, consume the event
+ // if so and move the focus to next/previous component
+ public void keyPressed(KeyEvent e) {
+ if (e.getKeyCode() == KeyEvent.VK_TAB) {
+ // Get the source of the event.
+ Object eventSrc = e.getSource();
+
+ // Check whether the source is a visible and enabled JRadioButton
+ if (isValidRadioButtonObj(eventSrc)) {
+ e.consume();
+ ButtonGroupInfo btnGroupInfo = new ButtonGroupInfo((JRadioButton)eventSrc);
+ btnGroupInfo.jumpToNextComponent(!e.isShiftDown());
+ }
+ }
+ }
+
+ public void keyReleased(KeyEvent e) {
+ }
+
+ public void keyTyped(KeyEvent e) {
+ }
+ }
}
--- a/jdk/src/java.desktop/share/classes/javax/swing/plaf/basic/BasicTabbedPaneUI.java Tue Oct 28 11:29:59 2014 -0400
+++ b/jdk/src/java.desktop/share/classes/javax/swing/plaf/basic/BasicTabbedPaneUI.java Tue Oct 28 17:17:05 2014 -0400
@@ -3249,6 +3249,7 @@
}
}
tabScroller.tabPanel.setPreferredSize(new Dimension(totalWidth, totalHeight));
+ tabScroller.tabPanel.invalidate();
}
}
@@ -3622,6 +3623,7 @@
setFocusIndex(tabPane.getSelectedIndex(), false);
if (scrollableTabLayoutEnabled()) {
+ ensureCurrentLayout();
int index = tabPane.getSelectedIndex();
if (index < rects.length && index != -1) {
tabScroller.tabPanel.scrollRectToVisible(
--- a/jdk/src/java.desktop/share/classes/javax/swing/text/html/HTMLDocument.java Tue Oct 28 11:29:59 2014 -0400
+++ b/jdk/src/java.desktop/share/classes/javax/swing/text/html/HTMLDocument.java Tue Oct 28 17:17:05 2014 -0400
@@ -1400,8 +1400,13 @@
Element parent = elem.getParentElement();
if (parent != null) {
+ // If we are going to insert the string into the body
+ // section, it is necessary to set the corrsponding flag.
+ if (HTML.Tag.BODY.name.equals(parent.getName())) {
+ insertInBody = true;
+ }
int offset = elem.getEndOffset();
- if (offset > getLength()) {
+ if (offset > (getLength() + 1)) {
offset--;
}
else if (elem.isLeaf() && getText(offset - 1, 1).
@@ -1409,6 +1414,10 @@
offset--;
}
insertHTML(parent, offset, htmlText, false);
+ // Cleanup the flag, if any.
+ if (insertInBody) {
+ insertInBody = false;
+ }
}
}
}
@@ -1847,6 +1856,11 @@
private static char[] NEWLINE;
/**
+ * Indicates that direct insertion to body section takes place.
+ */
+ private boolean insertInBody = false;
+
+ /**
* I18N property key.
*
* @see AbstractDocument#I18NProperty
@@ -2610,7 +2624,9 @@
// Assume content should be added.
foundInsertTag(false);
foundInsertTag = true;
- inParagraph = impliedP = true;
+ // If content is added directly to the body, it should
+ // be wrapped by p-implied.
+ inParagraph = impliedP = !insertInBody;
}
if (data.length >= 1) {
addContent(data, 0, data.length);
--- a/jdk/src/java.desktop/share/classes/sun/java2d/opengl/OGLBlitLoops.java Tue Oct 28 11:29:59 2014 -0400
+++ b/jdk/src/java.desktop/share/classes/sun/java2d/opengl/OGLBlitLoops.java Tue Oct 28 17:17:05 2014 -0400
@@ -47,7 +47,7 @@
import static sun.java2d.pipe.BufferedOpCodes.*;
import java.lang.annotation.Native;
-class OGLBlitLoops {
+final class OGLBlitLoops {
static void register() {
Blit blitIntArgbPreToSurface =
@@ -56,7 +56,9 @@
Blit blitIntArgbPreToTexture =
new OGLSwToTextureBlit(SurfaceType.IntArgbPre,
OGLSurfaceData.PF_INT_ARGB_PRE);
-
+ TransformBlit transformBlitIntArgbPreToSurface =
+ new OGLSwToSurfaceTransform(SurfaceType.IntArgbPre,
+ OGLSurfaceData.PF_INT_ARGB_PRE);
GraphicsPrimitive[] primitives = {
// surface->surface ops
new OGLSurfaceToSurfaceBlit(),
@@ -100,7 +102,7 @@
CompositeType.AnyAlpha,
blitIntArgbPreToSurface),
- new OGLAnyCompositeBlit(OGLSurfaceData.OpenGLSurface),
+ new OGLAnyCompositeBlit(),
new OGLSwToSurfaceScale(SurfaceType.IntRgb,
OGLSurfaceData.PF_INT_RGB),
@@ -145,8 +147,9 @@
OGLSurfaceData.PF_BYTE_GRAY),
new OGLSwToSurfaceTransform(SurfaceType.UshortGray,
OGLSurfaceData.PF_USHORT_GRAY),
- new OGLSwToSurfaceTransform(SurfaceType.IntArgbPre,
- OGLSurfaceData.PF_INT_ARGB_PRE),
+ transformBlitIntArgbPreToSurface,
+
+ new OGLGeneralTransformedBlit(transformBlitIntArgbPreToSurface),
// texture->surface ops
new OGLTextureToSurfaceBlit(),
@@ -178,9 +181,6 @@
new OGLGeneralBlit(OGLSurfaceData.OpenGLTexture,
CompositeType.SrcNoEa,
blitIntArgbPreToTexture),
-
- new OGLAnyCompositeBlit(OGLSurfaceData.OpenGLTexture),
-
};
GraphicsPrimitiveMgr.register(primitives);
}
@@ -781,11 +781,11 @@
* This general Blit implementation converts any source surface to an
* intermediate IntArgbPre surface, and then uses the more specific
* IntArgbPre->OpenGLSurface/Texture loop to get the intermediate
- * (premultiplied) surface down to OpenGL.
+ * (premultiplied) surface down to OpenGL using simple blit.
*/
class OGLGeneralBlit extends Blit {
- private Blit performop;
+ private final Blit performop;
private WeakReference<SurfaceData> srcTmp;
OGLGeneralBlit(SurfaceType dstType,
@@ -826,12 +826,56 @@
}
}
-class OGLAnyCompositeBlit extends Blit {
+/**
+ * This general TransformedBlit implementation converts any source surface to an
+ * intermediate IntArgbPre surface, and then uses the more specific
+ * IntArgbPre->OpenGLSurface/Texture loop to get the intermediate
+ * (premultiplied) surface down to OpenGL using simple transformBlit.
+ */
+final class OGLGeneralTransformedBlit extends TransformBlit {
+
+ private final TransformBlit performop;
+ private WeakReference<SurfaceData> srcTmp;
+
+ OGLGeneralTransformedBlit(final TransformBlit performop) {
+ super(SurfaceType.Any, CompositeType.AnyAlpha,
+ OGLSurfaceData.OpenGLSurface);
+ this.performop = performop;
+ }
+
+ @Override
+ public synchronized void Transform(SurfaceData src, SurfaceData dst,
+ Composite comp, Region clip,
+ AffineTransform at, int hint, int srcx,
+ int srcy, int dstx, int dsty, int width,
+ int height){
+ Blit convertsrc = Blit.getFromCache(src.getSurfaceType(),
+ CompositeType.SrcNoEa,
+ SurfaceType.IntArgbPre);
+ // use cached intermediate surface, if available
+ final SurfaceData cachedSrc = srcTmp != null ? srcTmp.get() : null;
+ // convert source to IntArgbPre
+ src = convertFrom(convertsrc, src, srcx, srcy, width, height, cachedSrc,
+ BufferedImage.TYPE_INT_ARGB_PRE);
+
+ // transform IntArgbPre intermediate surface to OpenGL surface
+ performop.Transform(src, dst, comp, clip, at, hint, 0, 0, dstx, dsty,
+ width, height);
+
+ if (src != cachedSrc) {
+ // cache the intermediate surface
+ srcTmp = new WeakReference<>(src);
+ }
+ }
+}
+
+final class OGLAnyCompositeBlit extends Blit {
private WeakReference<SurfaceData> dstTmp;
- public OGLAnyCompositeBlit(SurfaceType dstType) {
- super(SurfaceType.Any, CompositeType.Any, dstType);
+ OGLAnyCompositeBlit() {
+ super(SurfaceType.Any, CompositeType.Any, OGLSurfaceData.OpenGLSurface);
}
+
public synchronized void Blit(SurfaceData src, SurfaceData dst,
Composite comp, Region clip,
int sx, int sy, int dx, int dy,
@@ -848,15 +892,15 @@
cachedDst = dstTmp.get();
}
- // convert source to IntArgbPre
+ // convert destination to IntArgbPre
SurfaceData dstBuffer = convertFrom(convertdst, dst, dx, dy, w, h,
cachedDst, BufferedImage.TYPE_INT_ARGB_PRE);
+ Region bufferClip =
+ clip == null ? null : clip.getTranslatedRegion(-dx, -dy);
Blit performop = Blit.getFromCache(src.getSurfaceType(),
CompositeType.Any, dstBuffer.getSurfaceType());
-
- performop.Blit(src, dstBuffer, comp, clip,
- sx, sy, 0, 0, w, h);
+ performop.Blit(src, dstBuffer, comp, bufferClip, sx, sy, 0, 0, w, h);
if (dstBuffer != cachedDst) {
// cache the intermediate surface
--- a/jdk/src/java.desktop/unix/classes/META-INF/services/javax.print.PrintServiceLookup Tue Oct 28 11:29:59 2014 -0400
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,2 +0,0 @@
-# Provider for Java Print Service
-sun.print.UnixPrintServiceLookup
--- a/jdk/src/java.desktop/unix/classes/META-INF/services/javax.print.StreamPrintServiceFactory Tue Oct 28 11:29:59 2014 -0400
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,2 +0,0 @@
-# Provider for Java 2D Stream print services.
-sun.print.PSStreamPrinterFactory
--- a/jdk/src/java.desktop/unix/classes/sun/awt/X11/XWM.java Tue Oct 28 11:29:59 2014 -0400
+++ b/jdk/src/java.desktop/unix/classes/sun/awt/X11/XWM.java Tue Oct 28 17:17:05 2014 -0400
@@ -595,8 +595,13 @@
return isNetWMName("Mutter") || isNetWMName("GNOME Shell");
}
+ static int awtWMNonReparenting = -1;
static boolean isNonReparentingWM() {
- return (XWM.getWMID() == XWM.COMPIZ_WM || XWM.getWMID() == XWM.LG3D_WM || XWM.getWMID() == XWM.CWM_WM);
+ if (awtWMNonReparenting == -1) {
+ awtWMNonReparenting = (XToolkit.getEnv("_JAVA_AWT_WM_NONREPARENTING") != null) ? 1 : 0;
+ }
+ return (awtWMNonReparenting == 1 || XWM.getWMID() == XWM.COMPIZ_WM
+ || XWM.getWMID() == XWM.LG3D_WM || XWM.getWMID() == XWM.CWM_WM);
}
/*
--- a/jdk/src/java.desktop/unix/classes/sun/print/CUPSPrinter.java Tue Oct 28 11:29:59 2014 -0400
+++ b/jdk/src/java.desktop/unix/classes/sun/print/CUPSPrinter.java Tue Oct 28 17:17:05 2014 -0400
@@ -324,8 +324,8 @@
* reported, exec lpstat -d which has all the Apple
* special behaviour for this built in.
*/
- if (UnixPrintServiceLookup.isMac()) {
- printerInfo[0] = UnixPrintServiceLookup.
+ if (PrintServiceLookupProvider.isMac()) {
+ printerInfo[0] = PrintServiceLookupProvider.
getDefaultPrinterNameSysV();
printerInfo[1] = null;
return printerInfo.clone();
--- a/jdk/src/java.desktop/unix/classes/sun/print/IPPPrintService.java Tue Oct 28 11:29:59 2014 -0400
+++ b/jdk/src/java.desktop/unix/classes/sun/print/IPPPrintService.java Tue Oct 28 17:17:05 2014 -0400
@@ -1047,7 +1047,7 @@
setting like collation. Therefore, we temporarily exclude
Linux.
*/
- if (!UnixPrintServiceLookup.isLinux()) {
+ if (!PrintServiceLookupProvider.isLinux()) {
catList.add(SheetCollate.class);
}
}
@@ -1641,7 +1641,7 @@
* Mac is using printer-info IPP attribute for its human-readable printer
* name and is also the identifier used in NSPrintInfo:setPrinter.
*/
- if (UnixPrintServiceLookup.isMac()) {
+ if (PrintServiceLookupProvider.isMac()) {
PrintServiceAttributeSet psaSet = this.getAttributes();
if (psaSet != null) {
PrinterInfo pName = (PrinterInfo)psaSet.get(PrinterInfo.class);
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.desktop/unix/classes/sun/print/PrintServiceLookupProvider.java Tue Oct 28 17:17:05 2014 -0400
@@ -0,0 +1,964 @@
+/*
+ * Copyright (c) 2000, 2014, Oracle and/or its affiliates. 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. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package sun.print;
+
+import java.io.BufferedReader;
+import java.io.FileInputStream;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Vector;
+import java.security.AccessController;
+import java.security.PrivilegedActionException;
+import java.security.PrivilegedExceptionAction;
+import javax.print.DocFlavor;
+import javax.print.MultiDocPrintService;
+import javax.print.PrintService;
+import javax.print.PrintServiceLookup;
+import javax.print.attribute.Attribute;
+import javax.print.attribute.AttributeSet;
+import javax.print.attribute.HashPrintRequestAttributeSet;
+import javax.print.attribute.HashPrintServiceAttributeSet;
+import javax.print.attribute.PrintRequestAttribute;
+import javax.print.attribute.PrintRequestAttributeSet;
+import javax.print.attribute.PrintServiceAttribute;
+import javax.print.attribute.PrintServiceAttributeSet;
+import javax.print.attribute.standard.PrinterName;
+import javax.print.attribute.standard.PrinterURI;
+import java.io.File;
+import java.io.FileReader;
+import java.net.URL;
+import java.nio.file.Files;
+
+/*
+ * Remind: This class uses solaris commands. We also need a linux
+ * version
+ */
+public class PrintServiceLookupProvider extends PrintServiceLookup
+ implements BackgroundServiceLookup, Runnable {
+
+ /* Remind: the current implementation is static, as its assumed
+ * its preferable to minimize creation of PrintService instances.
+ * Later we should add logic to add/remove services on the fly which
+ * will take a hit of needing to regather the list of services.
+ */
+ private String defaultPrinter;
+ private PrintService defaultPrintService;
+ private PrintService[] printServices; /* includes the default printer */
+ private Vector<BackgroundLookupListener> lookupListeners = null;
+ private static String debugPrefix = "PrintServiceLookupProvider>> ";
+ private static boolean pollServices = true;
+ private static final int DEFAULT_MINREFRESH = 120; // 2 minutes
+ private static int minRefreshTime = DEFAULT_MINREFRESH;
+
+
+ static String osname;
+
+ // List of commands used to deal with the printer queues on AIX
+ String[] lpNameComAix = {
+ "/usr/bin/lsallq",
+ "/usr/bin/lpstat -W -p|/usr/bin/expand|/usr/bin/cut -f1 -d' '",
+ "/usr/bin/lpstat -W -d|/usr/bin/expand|/usr/bin/cut -f1 -d' '",
+ "/usr/bin/lpstat -W -v"
+ };
+ private static final int aix_lsallq = 0;
+ private static final int aix_lpstat_p = 1;
+ private static final int aix_lpstat_d = 2;
+ private static final int aix_lpstat_v = 3;
+ private static int aix_defaultPrinterEnumeration = aix_lsallq;
+
+ static {
+ /* The system property "sun.java2d.print.polling"
+ * can be used to force the printing code to poll or not poll
+ * for PrintServices.
+ */
+ String pollStr = java.security.AccessController.doPrivileged(
+ new sun.security.action.GetPropertyAction("sun.java2d.print.polling"));
+
+ if (pollStr != null) {
+ if (pollStr.equalsIgnoreCase("true")) {
+ pollServices = true;
+ } else if (pollStr.equalsIgnoreCase("false")) {
+ pollServices = false;
+ }
+ }
+
+ /* The system property "sun.java2d.print.minRefreshTime"
+ * can be used to specify minimum refresh time (in seconds)
+ * for polling PrintServices. The default is 120.
+ */
+ String refreshTimeStr = java.security.AccessController.doPrivileged(
+ new sun.security.action.GetPropertyAction(
+ "sun.java2d.print.minRefreshTime"));
+
+ if (refreshTimeStr != null) {
+ try {
+ minRefreshTime = (new Integer(refreshTimeStr)).intValue();
+ } catch (NumberFormatException e) {
+ }
+ if (minRefreshTime < DEFAULT_MINREFRESH) {
+ minRefreshTime = DEFAULT_MINREFRESH;
+ }
+ }
+
+ osname = java.security.AccessController.doPrivileged(
+ new sun.security.action.GetPropertyAction("os.name"));
+
+ /* The system property "sun.java2d.print.aix.lpstat"
+ * can be used to force the usage of 'lpstat -p' to enumerate all
+ * printer queues. By default we use 'lsallq', because 'lpstat -p' can
+ * take lots of time if thousands of printers are attached to a server.
+ */
+ if (isAIX()) {
+ String aixPrinterEnumerator = java.security.AccessController.doPrivileged(
+ new sun.security.action.GetPropertyAction("sun.java2d.print.aix.lpstat"));
+
+ if (aixPrinterEnumerator != null) {
+ if (aixPrinterEnumerator.equalsIgnoreCase("lpstat")) {
+ aix_defaultPrinterEnumeration = aix_lpstat_p;
+ } else if (aixPrinterEnumerator.equalsIgnoreCase("lsallq")) {
+ aix_defaultPrinterEnumeration = aix_lsallq;
+ }
+ }
+ }
+ }
+
+ static boolean isMac() {
+ return osname.startsWith("Mac");
+ }
+
+ static boolean isSysV() {
+ return osname.equals("SunOS");
+ }
+
+ static boolean isLinux() {
+ return (osname.equals("Linux"));
+ }
+
+ static boolean isBSD() {
+ return (osname.equals("Linux") ||
+ osname.contains("OS X"));
+ }
+
+ static boolean isAIX() {
+ return osname.equals("AIX");
+ }
+
+ static final int UNINITIALIZED = -1;
+ static final int BSD_LPD = 0;
+ static final int BSD_LPD_NG = 1;
+
+ static int cmdIndex = UNINITIALIZED;
+
+ String[] lpcFirstCom = {
+ "/usr/sbin/lpc status | grep : | sed -ne '1,1 s/://p'",
+ "/usr/sbin/lpc status | grep -E '^[ 0-9a-zA-Z_-]*@' | awk -F'@' '{print $1}'"
+ };
+
+ String[] lpcAllCom = {
+ "/usr/sbin/lpc status all | grep : | sed -e 's/://'",
+ "/usr/sbin/lpc status all | grep -E '^[ 0-9a-zA-Z_-]*@' | awk -F'@' '{print $1}' | sort"
+ };
+
+ String[] lpcNameCom = {
+ "| grep : | sed -ne 's/://p'",
+ "| grep -E '^[ 0-9a-zA-Z_-]*@' | awk -F'@' '{print $1}'"
+ };
+
+
+ static int getBSDCommandIndex() {
+ String command = "/usr/sbin/lpc status all";
+ String[] names = execCmd(command);
+
+ if ((names == null) || (names.length == 0)) {
+ return BSD_LPD_NG;
+ }
+
+ for (int i=0; i<names.length; i++) {
+ if (names[i].indexOf('@') != -1) {
+ return BSD_LPD_NG;
+ }
+ }
+
+ return BSD_LPD;
+ }
+
+
+ public PrintServiceLookupProvider() {
+ // start the printer listener thread
+ if (pollServices) {
+ PrinterChangeListener thr = new PrinterChangeListener();
+ thr.setDaemon(true);
+ thr.start();
+ IPPPrintService.debug_println(debugPrefix+"polling turned on");
+ }
+ }
+
+ /* Want the PrintService which is default print service to have
+ * equality of reference with the equivalent in list of print services
+ * This isn't required by the API and there's a risk doing this will
+ * lead people to assume its guaranteed.
+ */
+ public synchronized PrintService[] getPrintServices() {
+ SecurityManager security = System.getSecurityManager();
+ if (security != null) {
+ security.checkPrintJobAccess();
+ }
+
+ if (printServices == null || !pollServices) {
+ refreshServices();
+ }
+ if (printServices == null) {
+ return new PrintService[0];
+ } else {
+ return printServices.clone();
+ }
+ }
+
+ private int addPrintServiceToList(ArrayList<PrintService> printerList, PrintService ps) {
+ int index = printerList.indexOf(ps);
+ // Check if PrintService with same name is already in the list.
+ if (CUPSPrinter.isCupsRunning() && index != -1) {
+ // Bug in Linux: Duplicate entry of a remote printer
+ // and treats it as local printer but it is returning wrong
+ // information when queried using IPP. Workaround is to remove it.
+ // Even CUPS ignores these entries as shown in lpstat or using
+ // their web configuration.
+ PrinterURI uri = ps.getAttribute(PrinterURI.class);
+ if (uri.getURI().getHost().equals("localhost")) {
+ IPPPrintService.debug_println(debugPrefix+"duplicate PrintService, ignoring the new local printer: "+ps);
+ return index; // Do not add this.
+ }
+ PrintService oldPS = printerList.get(index);
+ uri = oldPS.getAttribute(PrinterURI.class);
+ if (uri.getURI().getHost().equals("localhost")) {
+ IPPPrintService.debug_println(debugPrefix+"duplicate PrintService, removing existing local printer: "+oldPS);
+ printerList.remove(oldPS);
+ } else {
+ return index;
+ }
+ }
+ printerList.add(ps);
+ return (printerList.size() - 1);
+ }
+
+
+ // refreshes "printServices"
+ public synchronized void refreshServices() {
+ /* excludes the default printer */
+ String[] printers = null; // array of printer names
+ String[] printerURIs = null; //array of printer URIs
+
+ try {
+ getDefaultPrintService();
+ } catch (Throwable t) {
+ IPPPrintService.debug_println(debugPrefix+
+ "Exception getting default printer : " + t);
+ }
+ if (CUPSPrinter.isCupsRunning()) {
+ try {
+ printerURIs = CUPSPrinter.getAllPrinters();
+ IPPPrintService.debug_println("CUPS URIs = " + printerURIs);
+ if (printerURIs != null) {
+ for (int p = 0; p < printerURIs.length; p++) {
+ IPPPrintService.debug_println("URI="+printerURIs[p]);
+ }
+ }
+ } catch (Throwable t) {
+ IPPPrintService.debug_println(debugPrefix+
+ "Exception getting all CUPS printers : " + t);
+ }
+ if ((printerURIs != null) && (printerURIs.length > 0)) {
+ printers = new String[printerURIs.length];
+ for (int i=0; i<printerURIs.length; i++) {
+ int lastIndex = printerURIs[i].lastIndexOf("/");
+ printers[i] = printerURIs[i].substring(lastIndex+1);
+ }
+ }
+ } else {
+ if (isMac() || isSysV()) {
+ printers = getAllPrinterNamesSysV();
+ } else if (isAIX()) {
+ printers = getAllPrinterNamesAIX();
+ } else { //BSD
+ printers = getAllPrinterNamesBSD();
+ }
+ }
+
+ if (printers == null) {
+ if (defaultPrintService != null) {
+ printServices = new PrintService[1];
+ printServices[0] = defaultPrintService;
+ } else {
+ printServices = null;
+ }
+ return;
+ }
+
+ ArrayList<PrintService> printerList = new ArrayList<>();
+ int defaultIndex = -1;
+ for (int p=0; p<printers.length; p++) {
+ if (printers[p] == null) {
+ continue;
+ }
+ if ((defaultPrintService != null)
+ && printers[p].equals(getPrinterDestName(defaultPrintService))) {
+ defaultIndex = addPrintServiceToList(printerList, defaultPrintService);
+ } else {
+ if (printServices == null) {
+ IPPPrintService.debug_println(debugPrefix+
+ "total# of printers = "+printers.length);
+
+ if (CUPSPrinter.isCupsRunning()) {
+ try {
+ addPrintServiceToList(printerList,
+ new IPPPrintService(printers[p],
+ printerURIs[p],
+ true));
+ } catch (Exception e) {
+ IPPPrintService.debug_println(debugPrefix+
+ " getAllPrinters Exception "+
+ e);
+
+ }
+ } else {
+ printerList.add(new UnixPrintService(printers[p]));
+ }
+ } else {
+ int j;
+ for (j=0; j<printServices.length; j++) {
+ if (printServices[j] != null) {
+ if (printers[p].equals(getPrinterDestName(printServices[j]))) {
+ printerList.add(printServices[j]);
+ printServices[j] = null;
+ break;
+ }
+ }
+ }
+
+ if (j == printServices.length) { // not found?
+ if (CUPSPrinter.isCupsRunning()) {
+ try {
+ addPrintServiceToList(printerList,
+ new IPPPrintService(printers[p],
+ printerURIs[p],
+ true));
+ } catch (Exception e) {
+ IPPPrintService.debug_println(debugPrefix+
+ " getAllPrinters Exception "+
+ e);
+
+ }
+ } else {
+ printerList.add(new UnixPrintService(printers[p]));
+ }
+ }
+ }
+ }
+ }
+
+ // Look for deleted services and invalidate these
+ if (printServices != null) {
+ for (int j=0; j < printServices.length; j++) {
+ if ((printServices[j] instanceof UnixPrintService) &&
+ (!printServices[j].equals(defaultPrintService))) {
+ ((UnixPrintService)printServices[j]).invalidateService();
+ }
+ }
+ }
+
+ //if defaultService is not found in printerList
+ if (defaultIndex == -1 && defaultPrintService != null) {
+ defaultIndex = addPrintServiceToList(printerList, defaultPrintService);
+ }
+
+ printServices = printerList.toArray(new PrintService[] {});
+
+ // swap default with the first in the list
+ if (defaultIndex > 0) {
+ PrintService saveService = printServices[0];
+ printServices[0] = printServices[defaultIndex];
+ printServices[defaultIndex] = saveService;
+ }
+ }
+
+ private boolean matchesAttributes(PrintService service,
+ PrintServiceAttributeSet attributes) {
+
+ Attribute [] attrs = attributes.toArray();
+ for (int i=0; i<attrs.length; i++) {
+ @SuppressWarnings("unchecked")
+ Attribute serviceAttr
+ = service.getAttribute((Class<PrintServiceAttribute>)attrs[i].getCategory());
+ if (serviceAttr == null || !serviceAttr.equals(attrs[i])) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ /* This checks for validity of the printer name before passing as
+ * parameter to a shell command.
+ */
+ private boolean checkPrinterName(String s) {
+ char c;
+
+ for (int i=0; i < s.length(); i++) {
+ c = s.charAt(i);
+ if (Character.isLetterOrDigit(c) ||
+ c == '-' || c == '_' || c == '.' || c == '/') {
+ continue;
+ } else {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ /*
+ * Gets the printer name compatible with the list of printers returned by
+ * the system when we query default or all the available printers.
+ */
+ private String getPrinterDestName(PrintService ps) {
+ if (isMac()) {
+ return ((IPPPrintService)ps).getDest();
+ }
+ return ps.getName();
+ }
+
+ /* On a network with many (hundreds) of network printers, it
+ * can save several seconds if you know all you want is a particular
+ * printer, to ask for that printer rather than retrieving all printers.
+ */
+ private PrintService getServiceByName(PrinterName nameAttr) {
+ String name = nameAttr.getValue();
+ if (name == null || name.equals("") || !checkPrinterName(name)) {
+ return null;
+ }
+ /* check if all printers are already available */
+ if (printServices != null) {
+ for (PrintService printService : printServices) {
+ PrinterName printerName = printService.getAttribute(PrinterName.class);
+ if (printerName.getValue().equals(name)) {
+ return printService;
+ }
+ }
+ }
+ /* take CUPS into account first */
+ if (CUPSPrinter.isCupsRunning()) {
+ try {
+ return new IPPPrintService(name,
+ new URL("http://"+
+ CUPSPrinter.getServer()+":"+
+ CUPSPrinter.getPort()+"/"+
+ name));
+ } catch (Exception e) {
+ IPPPrintService.debug_println(debugPrefix+
+ " getServiceByName Exception "+
+ e);
+ }
+ }
+ /* fallback if nothing not having a printer at this point */
+ PrintService printer = null;
+ if (isMac() || isSysV()) {
+ printer = getNamedPrinterNameSysV(name);
+ } else if (isAIX()) {
+ printer = getNamedPrinterNameAIX(name);
+ } else {
+ printer = getNamedPrinterNameBSD(name);
+ }
+ return printer;
+ }
+
+ private PrintService[]
+ getPrintServices(PrintServiceAttributeSet serviceSet) {
+
+ if (serviceSet == null || serviceSet.isEmpty()) {
+ return getPrintServices();
+ }
+
+ /* Typically expect that if a service attribute is specified that
+ * its a printer name and there ought to be only one match.
+ * Directly retrieve that service and confirm
+ * that it meets the other requirements.
+ * If printer name isn't mentioned then go a slow path checking
+ * all printers if they meet the reqiremements.
+ */
+ PrintService[] services;
+ PrinterName name = (PrinterName)serviceSet.get(PrinterName.class);
+ PrintService defService;
+ if (name != null && (defService = getDefaultPrintService()) != null) {
+ /* To avoid execing a unix command see if the client is asking
+ * for the default printer by name, since we already have that
+ * initialised.
+ */
+
+ PrinterName defName = defService.getAttribute(PrinterName.class);
+
+ if (defName != null && name.equals(defName)) {
+ if (matchesAttributes(defService, serviceSet)) {
+ services = new PrintService[1];
+ services[0] = defService;
+ return services;
+ } else {
+ return new PrintService[0];
+ }
+ } else {
+ /* Its not the default service */
+ PrintService service = getServiceByName(name);
+ if (service != null &&
+ matchesAttributes(service, serviceSet)) {
+ services = new PrintService[1];
+ services[0] = service;
+ return services;
+ } else {
+ return new PrintService[0];
+ }
+ }
+ } else {
+ /* specified service attributes don't include a name.*/
+ Vector<PrintService> matchedServices = new Vector<>();
+ services = getPrintServices();
+ for (int i = 0; i< services.length; i++) {
+ if (matchesAttributes(services[i], serviceSet)) {
+ matchedServices.add(services[i]);
+ }
+ }
+ services = new PrintService[matchedServices.size()];
+ for (int i = 0; i< services.length; i++) {
+ services[i] = matchedServices.elementAt(i);
+ }
+ return services;
+ }
+ }
+
+ /*
+ * If service attributes are specified then there must be additional
+ * filtering.
+ */
+ public PrintService[] getPrintServices(DocFlavor flavor,
+ AttributeSet attributes) {
+ SecurityManager security = System.getSecurityManager();
+ if (security != null) {
+ security.checkPrintJobAccess();
+ }
+ PrintRequestAttributeSet requestSet = null;
+ PrintServiceAttributeSet serviceSet = null;
+
+ if (attributes != null && !attributes.isEmpty()) {
+
+ requestSet = new HashPrintRequestAttributeSet();
+ serviceSet = new HashPrintServiceAttributeSet();
+
+ Attribute[] attrs = attributes.toArray();
+ for (int i=0; i<attrs.length; i++) {
+ if (attrs[i] instanceof PrintRequestAttribute) {
+ requestSet.add(attrs[i]);
+ } else if (attrs[i] instanceof PrintServiceAttribute) {
+ serviceSet.add(attrs[i]);
+ }
+ }
+ }
+
+ PrintService[] services = getPrintServices(serviceSet);
+ if (services.length == 0) {
+ return services;
+ }
+
+ if (CUPSPrinter.isCupsRunning()) {
+ ArrayList<PrintService> matchingServices = new ArrayList<>();
+ for (int i=0; i<services.length; i++) {
+ try {
+ if (services[i].
+ getUnsupportedAttributes(flavor, requestSet) == null) {
+ matchingServices.add(services[i]);
+ }
+ } catch (IllegalArgumentException e) {
+ }
+ }
+ services = new PrintService[matchingServices.size()];
+ return matchingServices.toArray(services);
+
+ } else {
+ // We only need to compare 1 PrintService because all
+ // UnixPrintServices are the same anyway. We will not use
+ // default PrintService because it might be null.
+ PrintService service = services[0];
+ if ((flavor == null ||
+ service.isDocFlavorSupported(flavor)) &&
+ service.getUnsupportedAttributes(flavor, requestSet) == null)
+ {
+ return services;
+ } else {
+ return new PrintService[0];
+ }
+ }
+ }
+
+ /*
+ * return empty array as don't support multi docs
+ */
+ public MultiDocPrintService[]
+ getMultiDocPrintServices(DocFlavor[] flavors,
+ AttributeSet attributes) {
+ SecurityManager security = System.getSecurityManager();
+ if (security != null) {
+ security.checkPrintJobAccess();
+ }
+ return new MultiDocPrintService[0];
+ }
+
+
+ public synchronized PrintService getDefaultPrintService() {
+ SecurityManager security = System.getSecurityManager();
+ if (security != null) {
+ security.checkPrintJobAccess();
+ }
+
+ // clear defaultPrintService
+ defaultPrintService = null;
+ String psuri = null;
+
+ IPPPrintService.debug_println("isRunning ? "+
+ (CUPSPrinter.isCupsRunning()));
+ if (CUPSPrinter.isCupsRunning()) {
+ String[] printerInfo = CUPSPrinter.getDefaultPrinter();
+ if (printerInfo != null && printerInfo.length >= 2) {
+ defaultPrinter = printerInfo[0];
+ psuri = printerInfo[1];
+ }
+ } else {
+ if (isMac() || isSysV()) {
+ defaultPrinter = getDefaultPrinterNameSysV();
+ } else if (isAIX()) {
+ defaultPrinter = getDefaultPrinterNameAIX();
+ } else {
+ defaultPrinter = getDefaultPrinterNameBSD();
+ }
+ }
+ if (defaultPrinter == null) {
+ return null;
+ }
+ defaultPrintService = null;
+ if (printServices != null) {
+ for (int j=0; j<printServices.length; j++) {
+ if (defaultPrinter.equals(getPrinterDestName(printServices[j]))) {
+ defaultPrintService = printServices[j];
+ break;
+ }
+ }
+ }
+ if (defaultPrintService == null) {
+ if (CUPSPrinter.isCupsRunning()) {
+ try {
+ PrintService defaultPS;
+ if ((psuri != null) && !psuri.startsWith("file")) {
+ defaultPS = new IPPPrintService(defaultPrinter,
+ psuri, true);
+ } else {
+ defaultPS = new IPPPrintService(defaultPrinter,
+ new URL("http://"+
+ CUPSPrinter.getServer()+":"+
+ CUPSPrinter.getPort()+"/"+
+ defaultPrinter));
+ }
+ defaultPrintService = defaultPS;
+ } catch (Exception e) {
+ }
+ } else {
+ defaultPrintService = new UnixPrintService(defaultPrinter);
+ }
+ }
+
+ return defaultPrintService;
+ }
+
+ public synchronized void
+ getServicesInbackground(BackgroundLookupListener listener) {
+ if (printServices != null) {
+ listener.notifyServices(printServices);
+ } else {
+ if (lookupListeners == null) {
+ lookupListeners = new Vector<>();
+ lookupListeners.add(listener);
+ Thread lookupThread = new Thread(this);
+ lookupThread.start();
+ } else {
+ lookupListeners.add(listener);
+ }
+ }
+ }
+
+ /* This method isn't used in most cases because we rely on code in
+ * javax.print.PrintServiceLookup. This is needed just for the cases
+ * where those interfaces are by-passed.
+ */
+ private PrintService[] copyOf(PrintService[] inArr) {
+ if (inArr == null || inArr.length == 0) {
+ return inArr;
+ } else {
+ PrintService []outArr = new PrintService[inArr.length];
+ System.arraycopy(inArr, 0, outArr, 0, inArr.length);
+ return outArr;
+ }
+ }
+
+ public void run() {
+ PrintService[] services = getPrintServices();
+ synchronized (this) {
+ BackgroundLookupListener listener;
+ for (int i=0; i<lookupListeners.size(); i++) {
+ listener = lookupListeners.elementAt(i);
+ listener.notifyServices(copyOf(services));
+ }
+ lookupListeners = null;
+ }
+ }
+
+ private String getDefaultPrinterNameBSD() {
+ if (cmdIndex == UNINITIALIZED) {
+ cmdIndex = getBSDCommandIndex();
+ }
+ String[] names = execCmd(lpcFirstCom[cmdIndex]);
+ if (names == null || names.length == 0) {
+ return null;
+ }
+
+ if ((cmdIndex==BSD_LPD_NG) &&
+ (names[0].startsWith("missingprinter"))) {
+ return null;
+ }
+ return names[0];
+ }
+
+ private PrintService getNamedPrinterNameBSD(String name) {
+ if (cmdIndex == UNINITIALIZED) {
+ cmdIndex = getBSDCommandIndex();
+ }
+ String command = "/usr/sbin/lpc status " + name + lpcNameCom[cmdIndex];
+ String[] result = execCmd(command);
+
+ if (result == null || !(result[0].equals(name))) {
+ return null;
+ }
+ return new UnixPrintService(name);
+ }
+
+ private String[] getAllPrinterNamesBSD() {
+ if (cmdIndex == UNINITIALIZED) {
+ cmdIndex = getBSDCommandIndex();
+ }
+ String[] names = execCmd(lpcAllCom[cmdIndex]);
+ if (names == null || names.length == 0) {
+ return null;
+ }
+ return names;
+ }
+
+ static String getDefaultPrinterNameSysV() {
+ String defaultPrinter = "lp";
+ String command = "/usr/bin/lpstat -d";
+
+ String [] names = execCmd(command);
+ if (names == null || names.length == 0) {
+ return defaultPrinter;
+ } else {
+ int index = names[0].indexOf(":");
+ if (index == -1 || (names[0].length() <= index+1)) {
+ return null;
+ } else {
+ String name = names[0].substring(index+1).trim();
+ if (name.length() == 0) {
+ return null;
+ } else {
+ return name;
+ }
+ }
+ }
+ }
+
+ private PrintService getNamedPrinterNameSysV(String name) {
+
+ String command = "/usr/bin/lpstat -v " + name;
+ String []result = execCmd(command);
+
+ if (result == null || result[0].indexOf("unknown printer") > 0) {
+ return null;
+ } else {
+ return new UnixPrintService(name);
+ }
+ }
+
+ private String[] getAllPrinterNamesSysV() {
+ String defaultPrinter = "lp";
+ String command = "/usr/bin/lpstat -v|/usr/bin/expand|/usr/bin/cut -f3 -d' ' |/usr/bin/cut -f1 -d':' | /usr/bin/sort";
+
+ String [] names = execCmd(command);
+ ArrayList<String> printerNames = new ArrayList<>();
+ for (int i=0; i < names.length; i++) {
+ if (!names[i].equals("_default") &&
+ !names[i].equals(defaultPrinter) &&
+ !names[i].equals("")) {
+ printerNames.add(names[i]);
+ }
+ }
+ return printerNames.toArray(new String[printerNames.size()]);
+ }
+
+ private String getDefaultPrinterNameAIX() {
+ String[] names = execCmd(lpNameComAix[aix_lpstat_d]);
+ // Remove headers and bogus entries added by remote printers.
+ names = UnixPrintService.filterPrinterNamesAIX(names);
+ if (names == null || names.length != 1) {
+ // No default printer found
+ return null;
+ } else {
+ return names[0];
+ }
+ }
+
+ private PrintService getNamedPrinterNameAIX(String name) {
+ // On AIX there should be no blank after '-v'.
+ String[] result = execCmd(lpNameComAix[aix_lpstat_v] + name);
+ // Remove headers and bogus entries added by remote printers.
+ result = UnixPrintService.filterPrinterNamesAIX(result);
+ if (result == null || result.length != 1) {
+ return null;
+ } else {
+ return new UnixPrintService(name);
+ }
+ }
+
+ private String[] getAllPrinterNamesAIX() {
+ // Determine all printers of the system.
+ String [] names = execCmd(lpNameComAix[aix_defaultPrinterEnumeration]);
+
+ // Remove headers and bogus entries added by remote printers.
+ names = UnixPrintService.filterPrinterNamesAIX(names);
+
+ ArrayList<String> printerNames = new ArrayList<String>();
+ for ( int i=0; i < names.length; i++) {
+ printerNames.add(names[i]);
+ }
+ return printerNames.toArray(new String[printerNames.size()]);
+ }
+
+ static String[] execCmd(final String command) {
+ ArrayList<String> results = null;
+ try {
+ final String[] cmd = new String[3];
+ if (isSysV() || isAIX()) {
+ cmd[0] = "/usr/bin/sh";
+ cmd[1] = "-c";
+ cmd[2] = "env LC_ALL=C " + command;
+ } else {
+ cmd[0] = "/bin/sh";
+ cmd[1] = "-c";
+ cmd[2] = "LC_ALL=C " + command;
+ }
+
+ results = AccessController.doPrivileged(
+ new PrivilegedExceptionAction<ArrayList<String>>() {
+ public ArrayList<String> run() throws IOException {
+
+ Process proc;
+ BufferedReader bufferedReader = null;
+ File f = Files.createTempFile("prn","xc").toFile();
+ cmd[2] = cmd[2]+">"+f.getAbsolutePath();
+
+ proc = Runtime.getRuntime().exec(cmd);
+ try {
+ boolean done = false; // in case of interrupt.
+ while (!done) {
+ try {
+ proc.waitFor();
+ done = true;
+ } catch (InterruptedException e) {
+ }
+ }
+
+ if (proc.exitValue() == 0) {
+ FileReader reader = new FileReader(f);
+ bufferedReader = new BufferedReader(reader);
+ String line;
+ ArrayList<String> results = new ArrayList<>();
+ while ((line = bufferedReader.readLine())
+ != null) {
+ results.add(line);
+ }
+ return results;
+ }
+ } finally {
+ f.delete();
+ // promptly close all streams.
+ if (bufferedReader != null) {
+ bufferedReader.close();
+ }
+ proc.getInputStream().close();
+ proc.getErrorStream().close();
+ proc.getOutputStream().close();
+ }
+ return null;
+ }
+ });
+ } catch (PrivilegedActionException e) {
+ }
+ if (results == null) {
+ return new String[0];
+ } else {
+ return results.toArray(new String[results.size()]);
+ }
+ }
+
+ private class PrinterChangeListener extends Thread {
+
+ public void run() {
+ int refreshSecs;
+ while (true) {
+ try {
+ refreshServices();
+ } catch (Exception se) {
+ IPPPrintService.debug_println(debugPrefix+"Exception in refresh thread.");
+ break;
+ }
+
+ if ((printServices != null) &&
+ (printServices.length > minRefreshTime)) {
+ // compute new refresh time 1 printer = 1 sec
+ refreshSecs = printServices.length;
+ } else {
+ refreshSecs = minRefreshTime;
+ }
+ try {
+ sleep(refreshSecs * 1000);
+ } catch (InterruptedException e) {
+ break;
+ }
+ }
+ }
+ }
+}
--- a/jdk/src/java.desktop/unix/classes/sun/print/UnixPrintJob.java Tue Oct 28 11:29:59 2014 -0400
+++ b/jdk/src/java.desktop/unix/classes/sun/print/UnixPrintJob.java Tue Oct 28 17:17:05 2014 -0400
@@ -122,7 +122,7 @@
UnixPrintJob(PrintService service) {
this.service = service;
mDestination = service.getName();
- if (UnixPrintServiceLookup.isMac()) {
+ if (PrintServiceLookupProvider.isMac()) {
mDestination = ((IPPPrintService)service).getDest();
}
mDestType = UnixPrintJob.DESTPRINTER;
@@ -880,7 +880,7 @@
pFlags |= NOSHEET;
ncomps+=1;
}
- if (UnixPrintServiceLookup.osname.equals("SunOS")) {
+ if (PrintServiceLookupProvider.osname.equals("SunOS")) {
ncomps+=1; // lp uses 1 more arg than lpr (make a copy)
execCmd = new String[ncomps];
execCmd[n++] = "/usr/bin/lp";
--- a/jdk/src/java.desktop/unix/classes/sun/print/UnixPrintService.java Tue Oct 28 11:29:59 2014 -0400
+++ b/jdk/src/java.desktop/unix/classes/sun/print/UnixPrintService.java Tue Oct 28 17:17:05 2014 -0400
@@ -220,7 +220,7 @@
private PrinterIsAcceptingJobs getPrinterIsAcceptingJobsSysV() {
String command = "/usr/bin/lpstat -a " + printer;
- String results[]= UnixPrintServiceLookup.execCmd(command);
+ String results[]= PrintServiceLookupProvider.execCmd(command);
if (results != null && results.length > 0) {
if (results[0].startsWith(printer + " accepting requests")) {
@@ -244,20 +244,20 @@
}
private PrinterIsAcceptingJobs getPrinterIsAcceptingJobsBSD() {
- if (UnixPrintServiceLookup.cmdIndex ==
- UnixPrintServiceLookup.UNINITIALIZED) {
+ if (PrintServiceLookupProvider.cmdIndex ==
+ PrintServiceLookupProvider.UNINITIALIZED) {
- UnixPrintServiceLookup.cmdIndex =
- UnixPrintServiceLookup.getBSDCommandIndex();
+ PrintServiceLookupProvider.cmdIndex =
+ PrintServiceLookupProvider.getBSDCommandIndex();
}
String command = "/usr/sbin/lpc status " + printer
- + lpcStatusCom[UnixPrintServiceLookup.cmdIndex];
- String results[]= UnixPrintServiceLookup.execCmd(command);
+ + lpcStatusCom[PrintServiceLookupProvider.cmdIndex];
+ String results[]= PrintServiceLookupProvider.execCmd(command);
if (results != null && results.length > 0) {
- if (UnixPrintServiceLookup.cmdIndex ==
- UnixPrintServiceLookup.BSD_LPD_NG) {
+ if (PrintServiceLookupProvider.cmdIndex ==
+ PrintServiceLookupProvider.BSD_LPD_NG) {
if (results[0].startsWith("enabled enabled")) {
return PrinterIsAcceptingJobs.ACCEPTING_JOBS ;
}
@@ -276,7 +276,7 @@
// Filter the list of possible AIX Printers and remove header lines
// and extra lines which have been added for remote printers.
- // 'protected' because this method is also used from UnixPrintServiceLookup.
+ // 'protected' because this method is also used from PrintServiceLookupProvider.
protected static String[] filterPrinterNamesAIX(String[] posPrinters) {
ArrayList<String> printers = new ArrayList<>();
String [] splitPart;
@@ -301,7 +301,7 @@
private PrinterIsAcceptingJobs getPrinterIsAcceptingJobsAIX() {
// On AIX there should not be a blank after '-a'.
String command = "/usr/bin/lpstat -a" + printer;
- String results[]= UnixPrintServiceLookup.execCmd(command);
+ String results[]= PrintServiceLookupProvider.execCmd(command);
// Remove headers and bogus entries added by remote printers.
results = filterPrinterNamesAIX(results);
@@ -320,11 +320,11 @@
}
private PrinterIsAcceptingJobs getPrinterIsAcceptingJobs() {
- if (UnixPrintServiceLookup.isSysV()) {
+ if (PrintServiceLookupProvider.isSysV()) {
return getPrinterIsAcceptingJobsSysV();
- } else if (UnixPrintServiceLookup.isBSD()) {
+ } else if (PrintServiceLookupProvider.isBSD()) {
return getPrinterIsAcceptingJobsBSD();
- } else if (UnixPrintServiceLookup.isAIX()) {
+ } else if (PrintServiceLookupProvider.isAIX()) {
return getPrinterIsAcceptingJobsAIX();
} else {
return PrinterIsAcceptingJobs.ACCEPTING_JOBS;
@@ -351,29 +351,29 @@
private QueuedJobCount getQueuedJobCountSysV() {
String command = "/usr/bin/lpstat -R " + printer;
- String results[]= UnixPrintServiceLookup.execCmd(command);
+ String results[]= PrintServiceLookupProvider.execCmd(command);
int qlen = (results == null) ? 0 : results.length;
return new QueuedJobCount(qlen);
}
private QueuedJobCount getQueuedJobCountBSD() {
- if (UnixPrintServiceLookup.cmdIndex ==
- UnixPrintServiceLookup.UNINITIALIZED) {
+ if (PrintServiceLookupProvider.cmdIndex ==
+ PrintServiceLookupProvider.UNINITIALIZED) {
- UnixPrintServiceLookup.cmdIndex =
- UnixPrintServiceLookup.getBSDCommandIndex();
+ PrintServiceLookupProvider.cmdIndex =
+ PrintServiceLookupProvider.getBSDCommandIndex();
}
int qlen = 0;
String command = "/usr/sbin/lpc status " + printer
- + lpcQueueCom[UnixPrintServiceLookup.cmdIndex];
- String results[] = UnixPrintServiceLookup.execCmd(command);
+ + lpcQueueCom[PrintServiceLookupProvider.cmdIndex];
+ String results[] = PrintServiceLookupProvider.execCmd(command);
if (results != null && results.length > 0) {
String queued;
- if (UnixPrintServiceLookup.cmdIndex ==
- UnixPrintServiceLookup.BSD_LPD_NG) {
+ if (PrintServiceLookupProvider.cmdIndex ==
+ PrintServiceLookupProvider.BSD_LPD_NG) {
queued = results[0];
} else {
queued = results[3].trim();
@@ -396,7 +396,7 @@
private QueuedJobCount getQueuedJobCountAIX() {
// On AIX there should not be a blank after '-a'.
String command = "/usr/bin/lpstat -a" + printer;
- String results[]= UnixPrintServiceLookup.execCmd(command);
+ String results[]= PrintServiceLookupProvider.execCmd(command);
// Remove headers and bogus entries added by remote printers.
results = filterPrinterNamesAIX(results);
@@ -413,11 +413,11 @@
}
private QueuedJobCount getQueuedJobCount() {
- if (UnixPrintServiceLookup.isSysV()) {
+ if (PrintServiceLookupProvider.isSysV()) {
return getQueuedJobCountSysV();
- } else if (UnixPrintServiceLookup.isBSD()) {
+ } else if (PrintServiceLookupProvider.isBSD()) {
return getQueuedJobCountBSD();
- } else if (UnixPrintServiceLookup.isAIX()) {
+ } else if (PrintServiceLookupProvider.isAIX()) {
return getQueuedJobCountAIX();
} else {
return new QueuedJobCount(0);
@@ -468,9 +468,9 @@
}
private PrintServiceAttributeSet getDynamicAttributes() {
- if (UnixPrintServiceLookup.isSysV()) {
+ if (PrintServiceLookupProvider.isSysV()) {
return getSysVServiceAttributes();
- } else if (UnixPrintServiceLookup.isAIX()) {
+ } else if (PrintServiceLookupProvider.isAIX()) {
return getAIXServiceAttributes();
} else {
return getBSDServiceAttributes();
--- a/jdk/src/java.desktop/unix/classes/sun/print/UnixPrintServiceLookup.java Tue Oct 28 11:29:59 2014 -0400
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,964 +0,0 @@
-/*
- * Copyright (c) 2000, 2014, Oracle and/or its affiliates. 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. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package sun.print;
-
-import java.io.BufferedReader;
-import java.io.FileInputStream;
-import java.io.InputStream;
-import java.io.InputStreamReader;
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Vector;
-import java.security.AccessController;
-import java.security.PrivilegedActionException;
-import java.security.PrivilegedExceptionAction;
-import javax.print.DocFlavor;
-import javax.print.MultiDocPrintService;
-import javax.print.PrintService;
-import javax.print.PrintServiceLookup;
-import javax.print.attribute.Attribute;
-import javax.print.attribute.AttributeSet;
-import javax.print.attribute.HashPrintRequestAttributeSet;
-import javax.print.attribute.HashPrintServiceAttributeSet;
-import javax.print.attribute.PrintRequestAttribute;
-import javax.print.attribute.PrintRequestAttributeSet;
-import javax.print.attribute.PrintServiceAttribute;
-import javax.print.attribute.PrintServiceAttributeSet;
-import javax.print.attribute.standard.PrinterName;
-import javax.print.attribute.standard.PrinterURI;
-import java.io.File;
-import java.io.FileReader;
-import java.net.URL;
-import java.nio.file.Files;
-
-/*
- * Remind: This class uses solaris commands. We also need a linux
- * version
- */
-public class UnixPrintServiceLookup extends PrintServiceLookup
- implements BackgroundServiceLookup, Runnable {
-
- /* Remind: the current implementation is static, as its assumed
- * its preferable to minimize creation of PrintService instances.
- * Later we should add logic to add/remove services on the fly which
- * will take a hit of needing to regather the list of services.
- */
- private String defaultPrinter;
- private PrintService defaultPrintService;
- private PrintService[] printServices; /* includes the default printer */
- private Vector<BackgroundLookupListener> lookupListeners = null;
- private static String debugPrefix = "UnixPrintServiceLookup>> ";
- private static boolean pollServices = true;
- private static final int DEFAULT_MINREFRESH = 120; // 2 minutes
- private static int minRefreshTime = DEFAULT_MINREFRESH;
-
-
- static String osname;
-
- // List of commands used to deal with the printer queues on AIX
- String[] lpNameComAix = {
- "/usr/bin/lsallq",
- "/usr/bin/lpstat -W -p|/usr/bin/expand|/usr/bin/cut -f1 -d' '",
- "/usr/bin/lpstat -W -d|/usr/bin/expand|/usr/bin/cut -f1 -d' '",
- "/usr/bin/lpstat -W -v"
- };
- private static final int aix_lsallq = 0;
- private static final int aix_lpstat_p = 1;
- private static final int aix_lpstat_d = 2;
- private static final int aix_lpstat_v = 3;
- private static int aix_defaultPrinterEnumeration = aix_lsallq;
-
- static {
- /* The system property "sun.java2d.print.polling"
- * can be used to force the printing code to poll or not poll
- * for PrintServices.
- */
- String pollStr = java.security.AccessController.doPrivileged(
- new sun.security.action.GetPropertyAction("sun.java2d.print.polling"));
-
- if (pollStr != null) {
- if (pollStr.equalsIgnoreCase("true")) {
- pollServices = true;
- } else if (pollStr.equalsIgnoreCase("false")) {
- pollServices = false;
- }
- }
-
- /* The system property "sun.java2d.print.minRefreshTime"
- * can be used to specify minimum refresh time (in seconds)
- * for polling PrintServices. The default is 120.
- */
- String refreshTimeStr = java.security.AccessController.doPrivileged(
- new sun.security.action.GetPropertyAction(
- "sun.java2d.print.minRefreshTime"));
-
- if (refreshTimeStr != null) {
- try {
- minRefreshTime = (new Integer(refreshTimeStr)).intValue();
- } catch (NumberFormatException e) {
- }
- if (minRefreshTime < DEFAULT_MINREFRESH) {
- minRefreshTime = DEFAULT_MINREFRESH;
- }
- }
-
- osname = java.security.AccessController.doPrivileged(
- new sun.security.action.GetPropertyAction("os.name"));
-
- /* The system property "sun.java2d.print.aix.lpstat"
- * can be used to force the usage of 'lpstat -p' to enumerate all
- * printer queues. By default we use 'lsallq', because 'lpstat -p' can
- * take lots of time if thousands of printers are attached to a server.
- */
- if (isAIX()) {
- String aixPrinterEnumerator = java.security.AccessController.doPrivileged(
- new sun.security.action.GetPropertyAction("sun.java2d.print.aix.lpstat"));
-
- if (aixPrinterEnumerator != null) {
- if (aixPrinterEnumerator.equalsIgnoreCase("lpstat")) {
- aix_defaultPrinterEnumeration = aix_lpstat_p;
- } else if (aixPrinterEnumerator.equalsIgnoreCase("lsallq")) {
- aix_defaultPrinterEnumeration = aix_lsallq;
- }
- }
- }
- }
-
- static boolean isMac() {
- return osname.startsWith("Mac");
- }
-
- static boolean isSysV() {
- return osname.equals("SunOS");
- }
-
- static boolean isLinux() {
- return (osname.equals("Linux"));
- }
-
- static boolean isBSD() {
- return (osname.equals("Linux") ||
- osname.contains("OS X"));
- }
-
- static boolean isAIX() {
- return osname.equals("AIX");
- }
-
- static final int UNINITIALIZED = -1;
- static final int BSD_LPD = 0;
- static final int BSD_LPD_NG = 1;
-
- static int cmdIndex = UNINITIALIZED;
-
- String[] lpcFirstCom = {
- "/usr/sbin/lpc status | grep : | sed -ne '1,1 s/://p'",
- "/usr/sbin/lpc status | grep -E '^[ 0-9a-zA-Z_-]*@' | awk -F'@' '{print $1}'"
- };
-
- String[] lpcAllCom = {
- "/usr/sbin/lpc status all | grep : | sed -e 's/://'",
- "/usr/sbin/lpc status all | grep -E '^[ 0-9a-zA-Z_-]*@' | awk -F'@' '{print $1}' | sort"
- };
-
- String[] lpcNameCom = {
- "| grep : | sed -ne 's/://p'",
- "| grep -E '^[ 0-9a-zA-Z_-]*@' | awk -F'@' '{print $1}'"
- };
-
-
- static int getBSDCommandIndex() {
- String command = "/usr/sbin/lpc status all";
- String[] names = execCmd(command);
-
- if ((names == null) || (names.length == 0)) {
- return BSD_LPD_NG;
- }
-
- for (int i=0; i<names.length; i++) {
- if (names[i].indexOf('@') != -1) {
- return BSD_LPD_NG;
- }
- }
-
- return BSD_LPD;
- }
-
-
- public UnixPrintServiceLookup() {
- // start the printer listener thread
- if (pollServices) {
- PrinterChangeListener thr = new PrinterChangeListener();
- thr.setDaemon(true);
- thr.start();
- IPPPrintService.debug_println(debugPrefix+"polling turned on");
- }
- }
-
- /* Want the PrintService which is default print service to have
- * equality of reference with the equivalent in list of print services
- * This isn't required by the API and there's a risk doing this will
- * lead people to assume its guaranteed.
- */
- public synchronized PrintService[] getPrintServices() {
- SecurityManager security = System.getSecurityManager();
- if (security != null) {
- security.checkPrintJobAccess();
- }
-
- if (printServices == null || !pollServices) {
- refreshServices();
- }
- if (printServices == null) {
- return new PrintService[0];
- } else {
- return printServices.clone();
- }
- }
-
- private int addPrintServiceToList(ArrayList<PrintService> printerList, PrintService ps) {
- int index = printerList.indexOf(ps);
- // Check if PrintService with same name is already in the list.
- if (CUPSPrinter.isCupsRunning() && index != -1) {
- // Bug in Linux: Duplicate entry of a remote printer
- // and treats it as local printer but it is returning wrong
- // information when queried using IPP. Workaround is to remove it.
- // Even CUPS ignores these entries as shown in lpstat or using
- // their web configuration.
- PrinterURI uri = ps.getAttribute(PrinterURI.class);
- if (uri.getURI().getHost().equals("localhost")) {
- IPPPrintService.debug_println(debugPrefix+"duplicate PrintService, ignoring the new local printer: "+ps);
- return index; // Do not add this.
- }
- PrintService oldPS = printerList.get(index);
- uri = oldPS.getAttribute(PrinterURI.class);
- if (uri.getURI().getHost().equals("localhost")) {
- IPPPrintService.debug_println(debugPrefix+"duplicate PrintService, removing existing local printer: "+oldPS);
- printerList.remove(oldPS);
- } else {
- return index;
- }
- }
- printerList.add(ps);
- return (printerList.size() - 1);
- }
-
-
- // refreshes "printServices"
- public synchronized void refreshServices() {
- /* excludes the default printer */
- String[] printers = null; // array of printer names
- String[] printerURIs = null; //array of printer URIs
-
- try {
- getDefaultPrintService();
- } catch (Throwable t) {
- IPPPrintService.debug_println(debugPrefix+
- "Exception getting default printer : " + t);
- }
- if (CUPSPrinter.isCupsRunning()) {
- try {
- printerURIs = CUPSPrinter.getAllPrinters();
- IPPPrintService.debug_println("CUPS URIs = " + printerURIs);
- if (printerURIs != null) {
- for (int p = 0; p < printerURIs.length; p++) {
- IPPPrintService.debug_println("URI="+printerURIs[p]);
- }
- }
- } catch (Throwable t) {
- IPPPrintService.debug_println(debugPrefix+
- "Exception getting all CUPS printers : " + t);
- }
- if ((printerURIs != null) && (printerURIs.length > 0)) {
- printers = new String[printerURIs.length];
- for (int i=0; i<printerURIs.length; i++) {
- int lastIndex = printerURIs[i].lastIndexOf("/");
- printers[i] = printerURIs[i].substring(lastIndex+1);
- }
- }
- } else {
- if (isMac() || isSysV()) {
- printers = getAllPrinterNamesSysV();
- } else if (isAIX()) {
- printers = getAllPrinterNamesAIX();
- } else { //BSD
- printers = getAllPrinterNamesBSD();
- }
- }
-
- if (printers == null) {
- if (defaultPrintService != null) {
- printServices = new PrintService[1];
- printServices[0] = defaultPrintService;
- } else {
- printServices = null;
- }
- return;
- }
-
- ArrayList<PrintService> printerList = new ArrayList<>();
- int defaultIndex = -1;
- for (int p=0; p<printers.length; p++) {
- if (printers[p] == null) {
- continue;
- }
- if ((defaultPrintService != null)
- && printers[p].equals(getPrinterDestName(defaultPrintService))) {
- defaultIndex = addPrintServiceToList(printerList, defaultPrintService);
- } else {
- if (printServices == null) {
- IPPPrintService.debug_println(debugPrefix+
- "total# of printers = "+printers.length);
-
- if (CUPSPrinter.isCupsRunning()) {
- try {
- addPrintServiceToList(printerList,
- new IPPPrintService(printers[p],
- printerURIs[p],
- true));
- } catch (Exception e) {
- IPPPrintService.debug_println(debugPrefix+
- " getAllPrinters Exception "+
- e);
-
- }
- } else {
- printerList.add(new UnixPrintService(printers[p]));
- }
- } else {
- int j;
- for (j=0; j<printServices.length; j++) {
- if (printServices[j] != null) {
- if (printers[p].equals(getPrinterDestName(printServices[j]))) {
- printerList.add(printServices[j]);
- printServices[j] = null;
- break;
- }
- }
- }
-
- if (j == printServices.length) { // not found?
- if (CUPSPrinter.isCupsRunning()) {
- try {
- addPrintServiceToList(printerList,
- new IPPPrintService(printers[p],
- printerURIs[p],
- true));
- } catch (Exception e) {
- IPPPrintService.debug_println(debugPrefix+
- " getAllPrinters Exception "+
- e);
-
- }
- } else {
- printerList.add(new UnixPrintService(printers[p]));
- }
- }
- }
- }
- }
-
- // Look for deleted services and invalidate these
- if (printServices != null) {
- for (int j=0; j < printServices.length; j++) {
- if ((printServices[j] instanceof UnixPrintService) &&
- (!printServices[j].equals(defaultPrintService))) {
- ((UnixPrintService)printServices[j]).invalidateService();
- }
- }
- }
-
- //if defaultService is not found in printerList
- if (defaultIndex == -1 && defaultPrintService != null) {
- defaultIndex = addPrintServiceToList(printerList, defaultPrintService);
- }
-
- printServices = printerList.toArray(new PrintService[] {});
-
- // swap default with the first in the list
- if (defaultIndex > 0) {
- PrintService saveService = printServices[0];
- printServices[0] = printServices[defaultIndex];
- printServices[defaultIndex] = saveService;
- }
- }
-
- private boolean matchesAttributes(PrintService service,
- PrintServiceAttributeSet attributes) {
-
- Attribute [] attrs = attributes.toArray();
- for (int i=0; i<attrs.length; i++) {
- @SuppressWarnings("unchecked")
- Attribute serviceAttr
- = service.getAttribute((Class<PrintServiceAttribute>)attrs[i].getCategory());
- if (serviceAttr == null || !serviceAttr.equals(attrs[i])) {
- return false;
- }
- }
- return true;
- }
-
- /* This checks for validity of the printer name before passing as
- * parameter to a shell command.
- */
- private boolean checkPrinterName(String s) {
- char c;
-
- for (int i=0; i < s.length(); i++) {
- c = s.charAt(i);
- if (Character.isLetterOrDigit(c) ||
- c == '-' || c == '_' || c == '.' || c == '/') {
- continue;
- } else {
- return false;
- }
- }
- return true;
- }
-
- /*
- * Gets the printer name compatible with the list of printers returned by
- * the system when we query default or all the available printers.
- */
- private String getPrinterDestName(PrintService ps) {
- if (isMac()) {
- return ((IPPPrintService)ps).getDest();
- }
- return ps.getName();
- }
-
- /* On a network with many (hundreds) of network printers, it
- * can save several seconds if you know all you want is a particular
- * printer, to ask for that printer rather than retrieving all printers.
- */
- private PrintService getServiceByName(PrinterName nameAttr) {
- String name = nameAttr.getValue();
- if (name == null || name.equals("") || !checkPrinterName(name)) {
- return null;
- }
- /* check if all printers are already available */
- if (printServices != null) {
- for (PrintService printService : printServices) {
- PrinterName printerName = printService.getAttribute(PrinterName.class);
- if (printerName.getValue().equals(name)) {
- return printService;
- }
- }
- }
- /* take CUPS into account first */
- if (CUPSPrinter.isCupsRunning()) {
- try {
- return new IPPPrintService(name,
- new URL("http://"+
- CUPSPrinter.getServer()+":"+
- CUPSPrinter.getPort()+"/"+
- name));
- } catch (Exception e) {
- IPPPrintService.debug_println(debugPrefix+
- " getServiceByName Exception "+
- e);
- }
- }
- /* fallback if nothing not having a printer at this point */
- PrintService printer = null;
- if (isMac() || isSysV()) {
- printer = getNamedPrinterNameSysV(name);
- } else if (isAIX()) {
- printer = getNamedPrinterNameAIX(name);
- } else {
- printer = getNamedPrinterNameBSD(name);
- }
- return printer;
- }
-
- private PrintService[]
- getPrintServices(PrintServiceAttributeSet serviceSet) {
-
- if (serviceSet == null || serviceSet.isEmpty()) {
- return getPrintServices();
- }
-
- /* Typically expect that if a service attribute is specified that
- * its a printer name and there ought to be only one match.
- * Directly retrieve that service and confirm
- * that it meets the other requirements.
- * If printer name isn't mentioned then go a slow path checking
- * all printers if they meet the reqiremements.
- */
- PrintService[] services;
- PrinterName name = (PrinterName)serviceSet.get(PrinterName.class);
- PrintService defService;
- if (name != null && (defService = getDefaultPrintService()) != null) {
- /* To avoid execing a unix command see if the client is asking
- * for the default printer by name, since we already have that
- * initialised.
- */
-
- PrinterName defName = defService.getAttribute(PrinterName.class);
-
- if (defName != null && name.equals(defName)) {
- if (matchesAttributes(defService, serviceSet)) {
- services = new PrintService[1];
- services[0] = defService;
- return services;
- } else {
- return new PrintService[0];
- }
- } else {
- /* Its not the default service */
- PrintService service = getServiceByName(name);
- if (service != null &&
- matchesAttributes(service, serviceSet)) {
- services = new PrintService[1];
- services[0] = service;
- return services;
- } else {
- return new PrintService[0];
- }
- }
- } else {
- /* specified service attributes don't include a name.*/
- Vector<PrintService> matchedServices = new Vector<>();
- services = getPrintServices();
- for (int i = 0; i< services.length; i++) {
- if (matchesAttributes(services[i], serviceSet)) {
- matchedServices.add(services[i]);
- }
- }
- services = new PrintService[matchedServices.size()];
- for (int i = 0; i< services.length; i++) {
- services[i] = matchedServices.elementAt(i);
- }
- return services;
- }
- }
-
- /*
- * If service attributes are specified then there must be additional
- * filtering.
- */
- public PrintService[] getPrintServices(DocFlavor flavor,
- AttributeSet attributes) {
- SecurityManager security = System.getSecurityManager();
- if (security != null) {
- security.checkPrintJobAccess();
- }
- PrintRequestAttributeSet requestSet = null;
- PrintServiceAttributeSet serviceSet = null;
-
- if (attributes != null && !attributes.isEmpty()) {
-
- requestSet = new HashPrintRequestAttributeSet();
- serviceSet = new HashPrintServiceAttributeSet();
-
- Attribute[] attrs = attributes.toArray();
- for (int i=0; i<attrs.length; i++) {
- if (attrs[i] instanceof PrintRequestAttribute) {
- requestSet.add(attrs[i]);
- } else if (attrs[i] instanceof PrintServiceAttribute) {
- serviceSet.add(attrs[i]);
- }
- }
- }
-
- PrintService[] services = getPrintServices(serviceSet);
- if (services.length == 0) {
- return services;
- }
-
- if (CUPSPrinter.isCupsRunning()) {
- ArrayList<PrintService> matchingServices = new ArrayList<>();
- for (int i=0; i<services.length; i++) {
- try {
- if (services[i].
- getUnsupportedAttributes(flavor, requestSet) == null) {
- matchingServices.add(services[i]);
- }
- } catch (IllegalArgumentException e) {
- }
- }
- services = new PrintService[matchingServices.size()];
- return matchingServices.toArray(services);
-
- } else {
- // We only need to compare 1 PrintService because all
- // UnixPrintServices are the same anyway. We will not use
- // default PrintService because it might be null.
- PrintService service = services[0];
- if ((flavor == null ||
- service.isDocFlavorSupported(flavor)) &&
- service.getUnsupportedAttributes(flavor, requestSet) == null)
- {
- return services;
- } else {
- return new PrintService[0];
- }
- }
- }
-
- /*
- * return empty array as don't support multi docs
- */
- public MultiDocPrintService[]
- getMultiDocPrintServices(DocFlavor[] flavors,
- AttributeSet attributes) {
- SecurityManager security = System.getSecurityManager();
- if (security != null) {
- security.checkPrintJobAccess();
- }
- return new MultiDocPrintService[0];
- }
-
-
- public synchronized PrintService getDefaultPrintService() {
- SecurityManager security = System.getSecurityManager();
- if (security != null) {
- security.checkPrintJobAccess();
- }
-
- // clear defaultPrintService
- defaultPrintService = null;
- String psuri = null;
-
- IPPPrintService.debug_println("isRunning ? "+
- (CUPSPrinter.isCupsRunning()));
- if (CUPSPrinter.isCupsRunning()) {
- String[] printerInfo = CUPSPrinter.getDefaultPrinter();
- if (printerInfo != null && printerInfo.length >= 2) {
- defaultPrinter = printerInfo[0];
- psuri = printerInfo[1];
- }
- } else {
- if (isMac() || isSysV()) {
- defaultPrinter = getDefaultPrinterNameSysV();
- } else if (isAIX()) {
- defaultPrinter = getDefaultPrinterNameAIX();
- } else {
- defaultPrinter = getDefaultPrinterNameBSD();
- }
- }
- if (defaultPrinter == null) {
- return null;
- }
- defaultPrintService = null;
- if (printServices != null) {
- for (int j=0; j<printServices.length; j++) {
- if (defaultPrinter.equals(getPrinterDestName(printServices[j]))) {
- defaultPrintService = printServices[j];
- break;
- }
- }
- }
- if (defaultPrintService == null) {
- if (CUPSPrinter.isCupsRunning()) {
- try {
- PrintService defaultPS;
- if ((psuri != null) && !psuri.startsWith("file")) {
- defaultPS = new IPPPrintService(defaultPrinter,
- psuri, true);
- } else {
- defaultPS = new IPPPrintService(defaultPrinter,
- new URL("http://"+
- CUPSPrinter.getServer()+":"+
- CUPSPrinter.getPort()+"/"+
- defaultPrinter));
- }
- defaultPrintService = defaultPS;
- } catch (Exception e) {
- }
- } else {
- defaultPrintService = new UnixPrintService(defaultPrinter);
- }
- }
-
- return defaultPrintService;
- }
-
- public synchronized void
- getServicesInbackground(BackgroundLookupListener listener) {
- if (printServices != null) {
- listener.notifyServices(printServices);
- } else {
- if (lookupListeners == null) {
- lookupListeners = new Vector<>();
- lookupListeners.add(listener);
- Thread lookupThread = new Thread(this);
- lookupThread.start();
- } else {
- lookupListeners.add(listener);
- }
- }
- }
-
- /* This method isn't used in most cases because we rely on code in
- * javax.print.PrintServiceLookup. This is needed just for the cases
- * where those interfaces are by-passed.
- */
- private PrintService[] copyOf(PrintService[] inArr) {
- if (inArr == null || inArr.length == 0) {
- return inArr;
- } else {
- PrintService []outArr = new PrintService[inArr.length];
- System.arraycopy(inArr, 0, outArr, 0, inArr.length);
- return outArr;
- }
- }
-
- public void run() {
- PrintService[] services = getPrintServices();
- synchronized (this) {
- BackgroundLookupListener listener;
- for (int i=0; i<lookupListeners.size(); i++) {
- listener = lookupListeners.elementAt(i);
- listener.notifyServices(copyOf(services));
- }
- lookupListeners = null;
- }
- }
-
- private String getDefaultPrinterNameBSD() {
- if (cmdIndex == UNINITIALIZED) {
- cmdIndex = getBSDCommandIndex();
- }
- String[] names = execCmd(lpcFirstCom[cmdIndex]);
- if (names == null || names.length == 0) {
- return null;
- }
-
- if ((cmdIndex==BSD_LPD_NG) &&
- (names[0].startsWith("missingprinter"))) {
- return null;
- }
- return names[0];
- }
-
- private PrintService getNamedPrinterNameBSD(String name) {
- if (cmdIndex == UNINITIALIZED) {
- cmdIndex = getBSDCommandIndex();
- }
- String command = "/usr/sbin/lpc status " + name + lpcNameCom[cmdIndex];
- String[] result = execCmd(command);
-
- if (result == null || !(result[0].equals(name))) {
- return null;
- }
- return new UnixPrintService(name);
- }
-
- private String[] getAllPrinterNamesBSD() {
- if (cmdIndex == UNINITIALIZED) {
- cmdIndex = getBSDCommandIndex();
- }
- String[] names = execCmd(lpcAllCom[cmdIndex]);
- if (names == null || names.length == 0) {
- return null;
- }
- return names;
- }
-
- static String getDefaultPrinterNameSysV() {
- String defaultPrinter = "lp";
- String command = "/usr/bin/lpstat -d";
-
- String [] names = execCmd(command);
- if (names == null || names.length == 0) {
- return defaultPrinter;
- } else {
- int index = names[0].indexOf(":");
- if (index == -1 || (names[0].length() <= index+1)) {
- return null;
- } else {
- String name = names[0].substring(index+1).trim();
- if (name.length() == 0) {
- return null;
- } else {
- return name;
- }
- }
- }
- }
-
- private PrintService getNamedPrinterNameSysV(String name) {
-
- String command = "/usr/bin/lpstat -v " + name;
- String []result = execCmd(command);
-
- if (result == null || result[0].indexOf("unknown printer") > 0) {
- return null;
- } else {
- return new UnixPrintService(name);
- }
- }
-
- private String[] getAllPrinterNamesSysV() {
- String defaultPrinter = "lp";
- String command = "/usr/bin/lpstat -v|/usr/bin/expand|/usr/bin/cut -f3 -d' ' |/usr/bin/cut -f1 -d':' | /usr/bin/sort";
-
- String [] names = execCmd(command);
- ArrayList<String> printerNames = new ArrayList<>();
- for (int i=0; i < names.length; i++) {
- if (!names[i].equals("_default") &&
- !names[i].equals(defaultPrinter) &&
- !names[i].equals("")) {
- printerNames.add(names[i]);
- }
- }
- return printerNames.toArray(new String[printerNames.size()]);
- }
-
- private String getDefaultPrinterNameAIX() {
- String[] names = execCmd(lpNameComAix[aix_lpstat_d]);
- // Remove headers and bogus entries added by remote printers.
- names = UnixPrintService.filterPrinterNamesAIX(names);
- if (names == null || names.length != 1) {
- // No default printer found
- return null;
- } else {
- return names[0];
- }
- }
-
- private PrintService getNamedPrinterNameAIX(String name) {
- // On AIX there should be no blank after '-v'.
- String[] result = execCmd(lpNameComAix[aix_lpstat_v] + name);
- // Remove headers and bogus entries added by remote printers.
- result = UnixPrintService.filterPrinterNamesAIX(result);
- if (result == null || result.length != 1) {
- return null;
- } else {
- return new UnixPrintService(name);
- }
- }
-
- private String[] getAllPrinterNamesAIX() {
- // Determine all printers of the system.
- String [] names = execCmd(lpNameComAix[aix_defaultPrinterEnumeration]);
-
- // Remove headers and bogus entries added by remote printers.
- names = UnixPrintService.filterPrinterNamesAIX(names);
-
- ArrayList<String> printerNames = new ArrayList<String>();
- for ( int i=0; i < names.length; i++) {
- printerNames.add(names[i]);
- }
- return printerNames.toArray(new String[printerNames.size()]);
- }
-
- static String[] execCmd(final String command) {
- ArrayList<String> results = null;
- try {
- final String[] cmd = new String[3];
- if (isSysV() || isAIX()) {
- cmd[0] = "/usr/bin/sh";
- cmd[1] = "-c";
- cmd[2] = "env LC_ALL=C " + command;
- } else {
- cmd[0] = "/bin/sh";
- cmd[1] = "-c";
- cmd[2] = "LC_ALL=C " + command;
- }
-
- results = AccessController.doPrivileged(
- new PrivilegedExceptionAction<ArrayList<String>>() {
- public ArrayList<String> run() throws IOException {
-
- Process proc;
- BufferedReader bufferedReader = null;
- File f = Files.createTempFile("prn","xc").toFile();
- cmd[2] = cmd[2]+">"+f.getAbsolutePath();
-
- proc = Runtime.getRuntime().exec(cmd);
- try {
- boolean done = false; // in case of interrupt.
- while (!done) {
- try {
- proc.waitFor();
- done = true;
- } catch (InterruptedException e) {
- }
- }
-
- if (proc.exitValue() == 0) {
- FileReader reader = new FileReader(f);
- bufferedReader = new BufferedReader(reader);
- String line;
- ArrayList<String> results = new ArrayList<>();
- while ((line = bufferedReader.readLine())
- != null) {
- results.add(line);
- }
- return results;
- }
- } finally {
- f.delete();
- // promptly close all streams.
- if (bufferedReader != null) {
- bufferedReader.close();
- }
- proc.getInputStream().close();
- proc.getErrorStream().close();
- proc.getOutputStream().close();
- }
- return null;
- }
- });
- } catch (PrivilegedActionException e) {
- }
- if (results == null) {
- return new String[0];
- } else {
- return results.toArray(new String[results.size()]);
- }
- }
-
- private class PrinterChangeListener extends Thread {
-
- public void run() {
- int refreshSecs;
- while (true) {
- try {
- refreshServices();
- } catch (Exception se) {
- IPPPrintService.debug_println(debugPrefix+"Exception in refresh thread.");
- break;
- }
-
- if ((printServices != null) &&
- (printServices.length > minRefreshTime)) {
- // compute new refresh time 1 printer = 1 sec
- refreshSecs = printServices.length;
- } else {
- refreshSecs = minRefreshTime;
- }
- try {
- sleep(refreshSecs * 1000);
- } catch (InterruptedException e) {
- break;
- }
- }
- }
- }
-}
--- a/jdk/src/java.desktop/unix/native/common/java2d/opengl/GLXGraphicsConfig.c Tue Oct 28 11:29:59 2014 -0400
+++ b/jdk/src/java.desktop/unix/native/common/java2d/opengl/GLXGraphicsConfig.c Tue Oct 28 17:17:05 2014 -0400
@@ -398,8 +398,8 @@
static GLXPbuffer
GLXGC_InitScratchPbuffer(GLXFBConfig fbconfig)
{
- int pbattrlist[] = {GLX_PBUFFER_WIDTH, 1,
- GLX_PBUFFER_HEIGHT, 1,
+ int pbattrlist[] = {GLX_PBUFFER_WIDTH, 4,
+ GLX_PBUFFER_HEIGHT, 4,
GLX_PRESERVED_CONTENTS, GL_FALSE,
0};
--- a/jdk/src/java.desktop/windows/classes/META-INF/services/javax.print.PrintServiceLookup Tue Oct 28 11:29:59 2014 -0400
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,2 +0,0 @@
-# Provider for Java Print Service
-sun.print.Win32PrintServiceLookup
--- a/jdk/src/java.desktop/windows/classes/META-INF/services/javax.print.StreamPrintServiceFactory Tue Oct 28 11:29:59 2014 -0400
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,2 +0,0 @@
-# Providers for Java 2D/JPS Stream print services.
-sun.print.PSStreamPrinterFactory
--- a/jdk/src/java.desktop/windows/classes/sun/awt/windows/WPathGraphics.java Tue Oct 28 11:29:59 2014 -0400
+++ b/jdk/src/java.desktop/windows/classes/sun/awt/windows/WPathGraphics.java Tue Oct 28 17:17:05 2014 -0400
@@ -1400,7 +1400,9 @@
* The saved device transform is needed as the current transform
* is not likely to be the same.
*/
- deviceClip(savedClip.getPathIterator(savedTransform));
+ if (savedClip != null) {
+ deviceClip(savedClip.getPathIterator(savedTransform));
+ }
/* Scale the bounding rectangle by the scale transform.
* Because the scaling transform has only x and y
--- a/jdk/src/java.desktop/windows/classes/sun/awt/windows/WPrinterJob.java Tue Oct 28 11:29:59 2014 -0400
+++ b/jdk/src/java.desktop/windows/classes/sun/awt/windows/WPrinterJob.java Tue Oct 28 17:17:05 2014 -0400
@@ -93,7 +93,7 @@
import sun.print.SunPageSelection;
import sun.print.Win32MediaTray;
import sun.print.Win32PrintService;
-import sun.print.Win32PrintServiceLookup;
+import sun.print.PrintServiceLookupProvider;
import sun.print.ServiceDialog;
import sun.print.DialogOwner;
@@ -454,7 +454,7 @@
// native printer is different !
// we update the current PrintService
try {
- setPrintService(Win32PrintServiceLookup.
+ setPrintService(PrintServiceLookupProvider.
getWin32PrintLUS().
getPrintServiceByName(printerName));
} catch (PrinterException e) {
@@ -628,7 +628,7 @@
String printerName = getNativePrintService();
if (printerName != null) {
- myService = Win32PrintServiceLookup.getWin32PrintLUS().
+ myService = PrintServiceLookupProvider.getWin32PrintLUS().
getPrintServiceByName(printerName);
// no need to call setNativePrintService as this name is
// currently set in native
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.desktop/windows/classes/sun/print/PrintServiceLookupProvider.java Tue Oct 28 17:17:05 2014 -0400
@@ -0,0 +1,349 @@
+/*
+ * Copyright (c) 2000, 2012, Oracle and/or its affiliates. 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. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package sun.print;
+
+import java.io.BufferedReader;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.security.AccessController;
+import java.security.PrivilegedActionException;
+import java.security.PrivilegedExceptionAction;
+import javax.print.DocFlavor;
+import javax.print.MultiDocPrintService;
+import javax.print.PrintService;
+import javax.print.PrintServiceLookup;
+import javax.print.attribute.Attribute;
+import javax.print.attribute.AttributeSet;
+import javax.print.attribute.HashPrintRequestAttributeSet;
+import javax.print.attribute.HashPrintServiceAttributeSet;
+import javax.print.attribute.PrintRequestAttribute;
+import javax.print.attribute.PrintRequestAttributeSet;
+import javax.print.attribute.PrintServiceAttribute;
+import javax.print.attribute.PrintServiceAttributeSet;
+import javax.print.attribute.standard.PrinterName;
+
+public class PrintServiceLookupProvider extends PrintServiceLookup {
+
+ private String defaultPrinter;
+ private PrintService defaultPrintService;
+ private String[] printers; /* excludes the default printer */
+ private PrintService[] printServices; /* includes the default printer */
+
+ static {
+ java.security.AccessController.doPrivileged(
+ new java.security.PrivilegedAction<Void>() {
+ public Void run() {
+ System.loadLibrary("awt");
+ return null;
+ }
+ });
+ }
+
+ /* The singleton win32 print lookup service.
+ * Code that is aware of this field and wants to use it must first
+ * see if its null, and if so instantiate it by calling a method such as
+ * javax.print.PrintServiceLookup.defaultPrintService() so that the
+ * same instance is stored there.
+ */
+ private static PrintServiceLookupProvider win32PrintLUS;
+
+ /* Think carefully before calling this. Preferably don't call it. */
+ public static PrintServiceLookupProvider getWin32PrintLUS() {
+ if (win32PrintLUS == null) {
+ /* This call is internally synchronized.
+ * When it returns an instance of this class will have
+ * been instantiated - else there's a JDK internal error.
+ */
+ PrintServiceLookup.lookupDefaultPrintService();
+ }
+ return win32PrintLUS;
+ }
+
+ public PrintServiceLookupProvider() {
+
+ if (win32PrintLUS == null) {
+ win32PrintLUS = this;
+
+ String osName = AccessController.doPrivileged(
+ new sun.security.action.GetPropertyAction("os.name"));
+ // There's no capability for Win98 to refresh printers.
+ // See "OpenPrinter" for more info.
+ if (osName != null && osName.startsWith("Windows 98")) {
+ return;
+ }
+ // start the printer listener thread
+ PrinterChangeListener thr = new PrinterChangeListener();
+ thr.setDaemon(true);
+ thr.start();
+ } /* else condition ought to never happen! */
+ }
+
+ /* Want the PrintService which is default print service to have
+ * equality of reference with the equivalent in list of print services
+ * This isn't required by the API and there's a risk doing this will
+ * lead people to assume its guaranteed.
+ */
+ public synchronized PrintService[] getPrintServices() {
+ SecurityManager security = System.getSecurityManager();
+ if (security != null) {
+ security.checkPrintJobAccess();
+ }
+ if (printServices == null) {
+ refreshServices();
+ }
+ return printServices;
+ }
+
+ private synchronized void refreshServices() {
+ printers = getAllPrinterNames();
+ if (printers == null) {
+ // In Windows it is safe to assume no default if printers == null so we
+ // don't get the default.
+ printServices = new PrintService[0];
+ return;
+ }
+
+ PrintService[] newServices = new PrintService[printers.length];
+ PrintService defService = getDefaultPrintService();
+ for (int p = 0; p < printers.length; p++) {
+ if (defService != null &&
+ printers[p].equals(defService.getName())) {
+ newServices[p] = defService;
+ } else {
+ if (printServices == null) {
+ newServices[p] = new Win32PrintService(printers[p]);
+ } else {
+ int j;
+ for (j = 0; j < printServices.length; j++) {
+ if ((printServices[j]!= null) &&
+ (printers[p].equals(printServices[j].getName()))) {
+ newServices[p] = printServices[j];
+ printServices[j] = null;
+ break;
+ }
+ }
+ if (j == printServices.length) {
+ newServices[p] = new Win32PrintService(printers[p]);
+ }
+ }
+ }
+ }
+
+ // Look for deleted services and invalidate these
+ if (printServices != null) {
+ for (int j=0; j < printServices.length; j++) {
+ if ((printServices[j] instanceof Win32PrintService) &&
+ (!printServices[j].equals(defaultPrintService))) {
+ ((Win32PrintService)printServices[j]).invalidateService();
+ }
+ }
+ }
+ printServices = newServices;
+ }
+
+
+ public synchronized PrintService getPrintServiceByName(String name) {
+
+ if (name == null || name.equals("")) {
+ return null;
+ } else {
+ /* getPrintServices() is now very fast. */
+ PrintService[] printServices = getPrintServices();
+ for (int i=0; i<printServices.length; i++) {
+ if (printServices[i].getName().equals(name)) {
+ return printServices[i];
+ }
+ }
+ return null;
+ }
+ }
+
+ @SuppressWarnings("unchecked") // Cast to Class<PrintServiceAttribute>
+ boolean matchingService(PrintService service,
+ PrintServiceAttributeSet serviceSet) {
+ if (serviceSet != null) {
+ Attribute [] attrs = serviceSet.toArray();
+ Attribute serviceAttr;
+ for (int i=0; i<attrs.length; i++) {
+ serviceAttr
+ = service.getAttribute((Class<PrintServiceAttribute>)attrs[i].getCategory());
+ if (serviceAttr == null || !serviceAttr.equals(attrs[i])) {
+ return false;
+ }
+ }
+ }
+ return true;
+ }
+
+ public PrintService[] getPrintServices(DocFlavor flavor,
+ AttributeSet attributes) {
+
+ SecurityManager security = System.getSecurityManager();
+ if (security != null) {
+ security.checkPrintJobAccess();
+ }
+ PrintRequestAttributeSet requestSet = null;
+ PrintServiceAttributeSet serviceSet = null;
+
+ if (attributes != null && !attributes.isEmpty()) {
+
+ requestSet = new HashPrintRequestAttributeSet();
+ serviceSet = new HashPrintServiceAttributeSet();
+
+ Attribute[] attrs = attributes.toArray();
+ for (int i=0; i<attrs.length; i++) {
+ if (attrs[i] instanceof PrintRequestAttribute) {
+ requestSet.add(attrs[i]);
+ } else if (attrs[i] instanceof PrintServiceAttribute) {
+ serviceSet.add(attrs[i]);
+ }
+ }
+ }
+
+ /*
+ * Special case: If client is asking for a particular printer
+ * (by name) then we can save time by getting just that service
+ * to check against the rest of the specified attributes.
+ */
+ PrintService[] services = null;
+ if (serviceSet != null && serviceSet.get(PrinterName.class) != null) {
+ PrinterName name = (PrinterName)serviceSet.get(PrinterName.class);
+ PrintService service = getPrintServiceByName(name.getValue());
+ if (service == null || !matchingService(service, serviceSet)) {
+ services = new PrintService[0];
+ } else {
+ services = new PrintService[1];
+ services[0] = service;
+ }
+ } else {
+ services = getPrintServices();
+ }
+
+ if (services.length == 0) {
+ return services;
+ } else {
+ ArrayList<PrintService> matchingServices = new ArrayList<>();
+ for (int i=0; i<services.length; i++) {
+ try {
+ if (services[i].
+ getUnsupportedAttributes(flavor, requestSet) == null) {
+ matchingServices.add(services[i]);
+ }
+ } catch (IllegalArgumentException e) {
+ }
+ }
+ services = new PrintService[matchingServices.size()];
+ return matchingServices.toArray(services);
+ }
+ }
+
+ /*
+ * return empty array as don't support multi docs
+ */
+ public MultiDocPrintService[]
+ getMultiDocPrintServices(DocFlavor[] flavors,
+ AttributeSet attributes) {
+ SecurityManager security = System.getSecurityManager();
+ if (security != null) {
+ security.checkPrintJobAccess();
+ }
+ return new MultiDocPrintService[0];
+ }
+
+
+ public synchronized PrintService getDefaultPrintService() {
+ SecurityManager security = System.getSecurityManager();
+ if (security != null) {
+ security.checkPrintJobAccess();
+ }
+
+
+ // Windows does not have notification for a change in default
+ // so we always get the latest.
+ defaultPrinter = getDefaultPrinterName();
+ if (defaultPrinter == null) {
+ return null;
+ }
+
+ if ((defaultPrintService != null) &&
+ defaultPrintService.getName().equals(defaultPrinter)) {
+
+ return defaultPrintService;
+ }
+
+ // Not the same as default so proceed to get new PrintService.
+
+ // clear defaultPrintService
+ defaultPrintService = null;
+
+ if (printServices != null) {
+ for (int j=0; j<printServices.length; j++) {
+ if (defaultPrinter.equals(printServices[j].getName())) {
+ defaultPrintService = printServices[j];
+ break;
+ }
+ }
+ }
+
+ if (defaultPrintService == null) {
+ defaultPrintService = new Win32PrintService(defaultPrinter);
+ }
+ return defaultPrintService;
+ }
+
+ class PrinterChangeListener extends Thread {
+ long chgObj;
+ PrinterChangeListener() {
+ chgObj = notifyFirstPrinterChange(null);
+ }
+
+ public void run() {
+ if (chgObj != -1) {
+ while (true) {
+ // wait for configuration to change
+ if (notifyPrinterChange(chgObj) != 0) {
+ try {
+ refreshServices();
+ } catch (SecurityException se) {
+ break;
+ }
+ } else {
+ notifyClosePrinterChange(chgObj);
+ break;
+ }
+ }
+ }
+ }
+ }
+
+ private native String getDefaultPrinterName();
+ private native String[] getAllPrinterNames();
+ private native long notifyFirstPrinterChange(String printer);
+ private native void notifyClosePrinterChange(long chgObj);
+ private native int notifyPrinterChange(long chgObj);
+}
--- a/jdk/src/java.desktop/windows/classes/sun/print/Win32PrintServiceLookup.java Tue Oct 28 11:29:59 2014 -0400
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,349 +0,0 @@
-/*
- * Copyright (c) 2000, 2012, Oracle and/or its affiliates. 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. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package sun.print;
-
-import java.io.BufferedReader;
-import java.io.InputStream;
-import java.io.InputStreamReader;
-import java.io.IOException;
-import java.util.ArrayList;
-import java.security.AccessController;
-import java.security.PrivilegedActionException;
-import java.security.PrivilegedExceptionAction;
-import javax.print.DocFlavor;
-import javax.print.MultiDocPrintService;
-import javax.print.PrintService;
-import javax.print.PrintServiceLookup;
-import javax.print.attribute.Attribute;
-import javax.print.attribute.AttributeSet;
-import javax.print.attribute.HashPrintRequestAttributeSet;
-import javax.print.attribute.HashPrintServiceAttributeSet;
-import javax.print.attribute.PrintRequestAttribute;
-import javax.print.attribute.PrintRequestAttributeSet;
-import javax.print.attribute.PrintServiceAttribute;
-import javax.print.attribute.PrintServiceAttributeSet;
-import javax.print.attribute.standard.PrinterName;
-
-public class Win32PrintServiceLookup extends PrintServiceLookup {
-
- private String defaultPrinter;
- private PrintService defaultPrintService;
- private String[] printers; /* excludes the default printer */
- private PrintService[] printServices; /* includes the default printer */
-
- static {
- java.security.AccessController.doPrivileged(
- new java.security.PrivilegedAction<Void>() {
- public Void run() {
- System.loadLibrary("awt");
- return null;
- }
- });
- }
-
- /* The singleton win32 print lookup service.
- * Code that is aware of this field and wants to use it must first
- * see if its null, and if so instantiate it by calling a method such as
- * javax.print.PrintServiceLookup.defaultPrintService() so that the
- * same instance is stored there.
- */
- private static Win32PrintServiceLookup win32PrintLUS;
-
- /* Think carefully before calling this. Preferably don't call it. */
- public static Win32PrintServiceLookup getWin32PrintLUS() {
- if (win32PrintLUS == null) {
- /* This call is internally synchronized.
- * When it returns an instance of this class will have
- * been instantiated - else there's a JDK internal error.
- */
- PrintServiceLookup.lookupDefaultPrintService();
- }
- return win32PrintLUS;
- }
-
- public Win32PrintServiceLookup() {
-
- if (win32PrintLUS == null) {
- win32PrintLUS = this;
-
- String osName = AccessController.doPrivileged(
- new sun.security.action.GetPropertyAction("os.name"));
- // There's no capability for Win98 to refresh printers.
- // See "OpenPrinter" for more info.
- if (osName != null && osName.startsWith("Windows 98")) {
- return;
- }
- // start the printer listener thread
- PrinterChangeListener thr = new PrinterChangeListener();
- thr.setDaemon(true);
- thr.start();
- } /* else condition ought to never happen! */
- }
-
- /* Want the PrintService which is default print service to have
- * equality of reference with the equivalent in list of print services
- * This isn't required by the API and there's a risk doing this will
- * lead people to assume its guaranteed.
- */
- public synchronized PrintService[] getPrintServices() {
- SecurityManager security = System.getSecurityManager();
- if (security != null) {
- security.checkPrintJobAccess();
- }
- if (printServices == null) {
- refreshServices();
- }
- return printServices;
- }
-
- private synchronized void refreshServices() {
- printers = getAllPrinterNames();
- if (printers == null) {
- // In Windows it is safe to assume no default if printers == null so we
- // don't get the default.
- printServices = new PrintService[0];
- return;
- }
-
- PrintService[] newServices = new PrintService[printers.length];
- PrintService defService = getDefaultPrintService();
- for (int p = 0; p < printers.length; p++) {
- if (defService != null &&
- printers[p].equals(defService.getName())) {
- newServices[p] = defService;
- } else {
- if (printServices == null) {
- newServices[p] = new Win32PrintService(printers[p]);
- } else {
- int j;
- for (j = 0; j < printServices.length; j++) {
- if ((printServices[j]!= null) &&
- (printers[p].equals(printServices[j].getName()))) {
- newServices[p] = printServices[j];
- printServices[j] = null;
- break;
- }
- }
- if (j == printServices.length) {
- newServices[p] = new Win32PrintService(printers[p]);
- }
- }
- }
- }
-
- // Look for deleted services and invalidate these
- if (printServices != null) {
- for (int j=0; j < printServices.length; j++) {
- if ((printServices[j] instanceof Win32PrintService) &&
- (!printServices[j].equals(defaultPrintService))) {
- ((Win32PrintService)printServices[j]).invalidateService();
- }
- }
- }
- printServices = newServices;
- }
-
-
- public synchronized PrintService getPrintServiceByName(String name) {
-
- if (name == null || name.equals("")) {
- return null;
- } else {
- /* getPrintServices() is now very fast. */
- PrintService[] printServices = getPrintServices();
- for (int i=0; i<printServices.length; i++) {
- if (printServices[i].getName().equals(name)) {
- return printServices[i];
- }
- }
- return null;
- }
- }
-
- @SuppressWarnings("unchecked") // Cast to Class<PrintServiceAttribute>
- boolean matchingService(PrintService service,
- PrintServiceAttributeSet serviceSet) {
- if (serviceSet != null) {
- Attribute [] attrs = serviceSet.toArray();
- Attribute serviceAttr;
- for (int i=0; i<attrs.length; i++) {
- serviceAttr
- = service.getAttribute((Class<PrintServiceAttribute>)attrs[i].getCategory());
- if (serviceAttr == null || !serviceAttr.equals(attrs[i])) {
- return false;
- }
- }
- }
- return true;
- }
-
- public PrintService[] getPrintServices(DocFlavor flavor,
- AttributeSet attributes) {
-
- SecurityManager security = System.getSecurityManager();
- if (security != null) {
- security.checkPrintJobAccess();
- }
- PrintRequestAttributeSet requestSet = null;
- PrintServiceAttributeSet serviceSet = null;
-
- if (attributes != null && !attributes.isEmpty()) {
-
- requestSet = new HashPrintRequestAttributeSet();
- serviceSet = new HashPrintServiceAttributeSet();
-
- Attribute[] attrs = attributes.toArray();
- for (int i=0; i<attrs.length; i++) {
- if (attrs[i] instanceof PrintRequestAttribute) {
- requestSet.add(attrs[i]);
- } else if (attrs[i] instanceof PrintServiceAttribute) {
- serviceSet.add(attrs[i]);
- }
- }
- }
-
- /*
- * Special case: If client is asking for a particular printer
- * (by name) then we can save time by getting just that service
- * to check against the rest of the specified attributes.
- */
- PrintService[] services = null;
- if (serviceSet != null && serviceSet.get(PrinterName.class) != null) {
- PrinterName name = (PrinterName)serviceSet.get(PrinterName.class);
- PrintService service = getPrintServiceByName(name.getValue());
- if (service == null || !matchingService(service, serviceSet)) {
- services = new PrintService[0];
- } else {
- services = new PrintService[1];
- services[0] = service;
- }
- } else {
- services = getPrintServices();
- }
-
- if (services.length == 0) {
- return services;
- } else {
- ArrayList<PrintService> matchingServices = new ArrayList<>();
- for (int i=0; i<services.length; i++) {
- try {
- if (services[i].
- getUnsupportedAttributes(flavor, requestSet) == null) {
- matchingServices.add(services[i]);
- }
- } catch (IllegalArgumentException e) {
- }
- }
- services = new PrintService[matchingServices.size()];
- return matchingServices.toArray(services);
- }
- }
-
- /*
- * return empty array as don't support multi docs
- */
- public MultiDocPrintService[]
- getMultiDocPrintServices(DocFlavor[] flavors,
- AttributeSet attributes) {
- SecurityManager security = System.getSecurityManager();
- if (security != null) {
- security.checkPrintJobAccess();
- }
- return new MultiDocPrintService[0];
- }
-
-
- public synchronized PrintService getDefaultPrintService() {
- SecurityManager security = System.getSecurityManager();
- if (security != null) {
- security.checkPrintJobAccess();
- }
-
-
- // Windows does not have notification for a change in default
- // so we always get the latest.
- defaultPrinter = getDefaultPrinterName();
- if (defaultPrinter == null) {
- return null;
- }
-
- if ((defaultPrintService != null) &&
- defaultPrintService.getName().equals(defaultPrinter)) {
-
- return defaultPrintService;
- }
-
- // Not the same as default so proceed to get new PrintService.
-
- // clear defaultPrintService
- defaultPrintService = null;
-
- if (printServices != null) {
- for (int j=0; j<printServices.length; j++) {
- if (defaultPrinter.equals(printServices[j].getName())) {
- defaultPrintService = printServices[j];
- break;
- }
- }
- }
-
- if (defaultPrintService == null) {
- defaultPrintService = new Win32PrintService(defaultPrinter);
- }
- return defaultPrintService;
- }
-
- class PrinterChangeListener extends Thread {
- long chgObj;
- PrinterChangeListener() {
- chgObj = notifyFirstPrinterChange(null);
- }
-
- public void run() {
- if (chgObj != -1) {
- while (true) {
- // wait for configuration to change
- if (notifyPrinterChange(chgObj) != 0) {
- try {
- refreshServices();
- } catch (SecurityException se) {
- break;
- }
- } else {
- notifyClosePrinterChange(chgObj);
- break;
- }
- }
- }
- }
- }
-
- private native String getDefaultPrinterName();
- private native String[] getAllPrinterNames();
- private native long notifyFirstPrinterChange(String printer);
- private native void notifyClosePrinterChange(long chgObj);
- private native int notifyPrinterChange(long chgObj);
-}
--- a/jdk/src/java.desktop/windows/native/libawt/windows/WPrinterJob.cpp Tue Oct 28 11:29:59 2014 -0400
+++ b/jdk/src/java.desktop/windows/native/libawt/windows/WPrinterJob.cpp Tue Oct 28 17:17:05 2014 -0400
@@ -68,7 +68,7 @@
extern "C" {
JNIEXPORT jstring JNICALL
-Java_sun_print_Win32PrintServiceLookup_getDefaultPrinterName(JNIEnv *env,
+Java_sun_print_PrintServiceLookupProvider_getDefaultPrinterName(JNIEnv *env,
jobject peer)
{
TRY;
@@ -119,7 +119,7 @@
JNIEXPORT jobjectArray JNICALL
-Java_sun_print_Win32PrintServiceLookup_getAllPrinterNames(JNIEnv *env,
+Java_sun_print_PrintServiceLookupProvider_getAllPrinterNames(JNIEnv *env,
jobject peer)
{
TRY;
@@ -176,7 +176,7 @@
JNIEXPORT jlong JNICALL
-Java_sun_print_Win32PrintServiceLookup_notifyFirstPrinterChange(JNIEnv *env,
+Java_sun_print_PrintServiceLookupProvider_notifyFirstPrinterChange(JNIEnv *env,
jobject peer,
jstring printer) {
HANDLE hPrinter;
@@ -210,7 +210,7 @@
JNIEXPORT void JNICALL
-Java_sun_print_Win32PrintServiceLookup_notifyClosePrinterChange(JNIEnv *env,
+Java_sun_print_PrintServiceLookupProvider_notifyClosePrinterChange(JNIEnv *env,
jobject peer,
jlong chgObject) {
FindClosePrinterChangeNotification((HANDLE)chgObject);
@@ -218,7 +218,7 @@
JNIEXPORT jint JNICALL
-Java_sun_print_Win32PrintServiceLookup_notifyPrinterChange(JNIEnv *env,
+Java_sun_print_PrintServiceLookupProvider_notifyPrinterChange(JNIEnv *env,
jobject peer,
jlong chgObject) {
DWORD dwChange;
--- a/jdk/src/java.desktop/windows/native/libawt/windows/awt_PrintControl.cpp Tue Oct 28 11:29:59 2014 -0400
+++ b/jdk/src/java.desktop/windows/native/libawt/windows/awt_PrintControl.cpp Tue Oct 28 17:17:05 2014 -0400
@@ -771,6 +771,17 @@
jint maxPage = env->CallIntMethod(printCtrl,
AwtPrintControl::getMaxPageID);
pd.nMaxPage = (maxPage <= (jint)((WORD)-1)) ? (WORD)maxPage : (WORD)-1;
+ // In the event that the application displays the dialog before
+ // installing a Printable, but sets a page range, then max page will be 1
+ // since the default state of a PrinterJob is an empty "Book" Pageable.
+ // Windows pops up an error dialog in such a case which isn't very
+ // forthcoming about the exact problem.
+ // So if we detect this fix up such a problem here.
+ if (pd.nMinPage > pd.nFromPage) pd.nMinPage = pd.nFromPage;
+ if (pd.nMaxPage < pd.nToPage) pd.nMaxPage = pd.nToPage;
+ if (pd.nFromPage > pd.nMinPage || pd.nToPage < pd.nMaxPage) {
+ pd.Flags |= PD_PAGENUMS;
+ }
if (env->CallBooleanMethod(printCtrl,
AwtPrintControl::getDestID)) {
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/awt/Container/ContainerAIOOBE/ContainerAIOOBE.java Tue Oct 28 17:17:05 2014 -0400
@@ -0,0 +1,74 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.awt.Button;
+import java.awt.Component;
+import java.awt.Container;
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+
+/**
+ * @test
+ * @bug 8059590
+ * @summary ArrayIndexOutOfBoundsException occurs when Container with overridden getComponents() is deserialized.
+ * @author Alexey Ivanov
+ * @run main ContainerAIOOBE
+ */
+public class ContainerAIOOBE {
+
+ public static void main(final String[] args) throws Exception {
+ ZContainer z = new ZContainer();
+ z.add(new Button());
+
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ ObjectOutputStream oos = new ObjectOutputStream(baos);
+ oos.writeObject(z);
+ oos.flush();
+ oos.close();
+
+ byte[] array = baos.toByteArray();
+ ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(array));
+
+ // Reading the object must not throw ArrayIndexOutOfBoundsException
+ ZContainer zz = (ZContainer) ois.readObject();
+
+ if (zz.getComponentCount() != 1) {
+ throw new Exception("deserialized object must have 1 component");
+ }
+ if (!(zz.getComponent(0) instanceof Button)) {
+ throw new Exception("deserialized object must contain Button component");
+ }
+ if (zz.getComponents().length != 0) {
+ throw new Exception("deserialized object returns non-empty array");
+ }
+ System.out.println("Test passed");
+ }
+
+ static class ZContainer extends Container {
+ public Component[] getComponents() {
+ return new Component[0];
+ }
+ }
+}
--- a/jdk/test/java/awt/GraphicsDevice/CloneConfigsTest.java Tue Oct 28 11:29:59 2014 -0400
+++ b/jdk/test/java/awt/GraphicsDevice/CloneConfigsTest.java Tue Oct 28 17:17:05 2014 -0400
@@ -23,7 +23,7 @@
/*
* @test
- * @bug 6822057 7124400
+ * @bug 6822057 7124400 8059848
*
* @summary Test verifies that list of supported graphics configurations
* can not be changed via modification of elements of an array
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/awt/color/LoadProfileWithSM.java Tue Oct 28 17:17:05 2014 -0400
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.awt.color.*;
+
+/*
+ * @test
+ * @bug 8058969
+ * @summary test standard profiles loads with SecurityManager installed.
+ * @run main/othervm LoadProfileWithSM
+ */
+
+public class LoadProfileWithSM {
+
+ public static void main(String[] args) {
+ System.setSecurityManager(new SecurityManager());
+ ICC_Profile profile =
+ ((ICC_ColorSpace)(ColorSpace.getInstance(
+ ColorSpace.CS_GRAY))).getProfile();
+ /* request profile data in order to force profile loading */
+ profile.getData();
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/awt/image/DrawImage/IncorrectClipXorModeSW2Surface.java Tue Oct 28 17:17:05 2014 -0400
@@ -0,0 +1,179 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.awt.Color;
+import java.awt.Graphics2D;
+import java.awt.GraphicsConfiguration;
+import java.awt.GraphicsEnvironment;
+import java.awt.Image;
+import java.awt.Rectangle;
+import java.awt.Shape;
+import java.awt.geom.AffineTransform;
+import java.awt.image.BufferedImage;
+import java.awt.image.DataBuffer;
+import java.awt.image.DataBufferByte;
+import java.awt.image.DataBufferInt;
+import java.awt.image.DataBufferShort;
+import java.awt.image.VolatileImage;
+import java.io.File;
+import java.io.IOException;
+
+import javax.imageio.ImageIO;
+
+import static java.awt.geom.Rectangle2D.Double;
+
+/**
+ * @test
+ * @bug 8061456
+ * @summary Tests drawing BI to volatile image using different clips + xor mode.
+ * Results of the blit BI to compatibleImage is used for comparison.
+ * @author Sergey Bylokhov
+ */
+public final class IncorrectClipXorModeSW2Surface {
+
+ private static int[] SIZES = {2, 10, 100};
+ private static final Shape[] SHAPES = {
+ new Rectangle(0, 0, 0, 0),
+ new Rectangle(0, 0, 1, 1),
+ new Rectangle(0, 1, 1, 1),
+ new Rectangle(1, 0, 1, 1),
+ new Rectangle(1, 1, 1, 1),
+
+ new Double(0, 0, 0.5, 0.5),
+ new Double(0, 0.5, 0.5, 0.5),
+ new Double(0.5, 0, 0.5, 0.5),
+ new Double(0.5, 0.5, 0.5, 0.5),
+ new Double(0.25, 0.25, 0.5, 0.5),
+ new Double(0, 0.25, 1, 0.5),
+ new Double(0.25, 0, 0.5, 1),
+
+ new Double(.10, .10, .20, .20),
+ new Double(.75, .75, .20, .20),
+ new Double(.75, .10, .20, .20),
+ new Double(.10, .75, .20, .20),
+ };
+
+ public static void main(final String[] args) throws IOException {
+ GraphicsEnvironment ge = GraphicsEnvironment
+ .getLocalGraphicsEnvironment();
+ GraphicsConfiguration gc = ge.getDefaultScreenDevice()
+ .getDefaultConfiguration();
+ AffineTransform at;
+ for (int size : SIZES) {
+ at = AffineTransform.getScaleInstance(size, size);
+ for (Shape clip : SHAPES) {
+ clip = at.createTransformedShape(clip);
+ for (Shape to : SHAPES) {
+ to = at.createTransformedShape(to);
+ // Prepare test images
+ BufferedImage snapshot;
+ BufferedImage bi = getBufferedImage(size);
+ VolatileImage vi = getVolatileImage(gc, size);
+ while (true) {
+ vi.validate(gc);
+ Graphics2D g2d = vi.createGraphics();
+ g2d.setColor(Color.GREEN);
+ g2d.fillRect(0, 0, size, size);
+ g2d.dispose();
+ if (vi.validate(gc) != VolatileImage.IMAGE_OK) {
+ continue;
+ }
+ draw(clip, to, bi, vi);
+ snapshot = vi.getSnapshot();
+ if (vi.contentsLost()) {
+ continue;
+ }
+ break;
+ }
+ // Prepare gold images
+ BufferedImage goldvi = getCompatibleImage(gc, size);
+ BufferedImage goldbi = getBufferedImage(size);
+ draw(clip, to, goldbi, goldvi);
+ validate(snapshot, goldvi);
+ vi.flush();
+ }
+ }
+ }
+ }
+
+ private static void draw(Shape clip, Shape shape, Image from, Image to) {
+ Graphics2D g2d = (Graphics2D) to.getGraphics();
+ g2d.setXORMode(Color.BLACK);
+ g2d.setClip(clip);
+ Rectangle toBounds = shape.getBounds();
+ g2d.drawImage(from, toBounds.x, toBounds.y, toBounds.width,
+ toBounds.height, null);
+ g2d.dispose();
+ }
+
+ private static BufferedImage getBufferedImage(int sw) {
+ final BufferedImage bi = new BufferedImage(sw, sw, BufferedImage.TYPE_INT_ARGB);
+ Graphics2D g2d = bi.createGraphics();
+ g2d.setColor(Color.RED);
+ g2d.fillRect(0, 0, sw, sw);
+ g2d.dispose();
+
+ final DataBuffer db = bi.getRaster().getDataBuffer();
+ if (db instanceof DataBufferInt) {
+ ((DataBufferInt) db).getData();
+ } else if (db instanceof DataBufferShort) {
+ ((DataBufferShort) db).getData();
+ } else if (db instanceof DataBufferByte) {
+ ((DataBufferByte) db).getData();
+ } else {
+ try {
+ bi.setAccelerationPriority(0.0f);
+ } catch (final Throwable ignored) {
+ }
+ }
+ return bi;
+ }
+
+ private static VolatileImage getVolatileImage(GraphicsConfiguration gc,
+ int size) {
+ return gc.createCompatibleVolatileImage(size, size);
+ }
+
+ private static BufferedImage getCompatibleImage(GraphicsConfiguration gc,
+ int size) {
+ BufferedImage image = gc.createCompatibleImage(size, size);
+ Graphics2D g2d = image.createGraphics();
+ g2d.setColor(Color.GREEN);
+ g2d.fillRect(0, 0, size, size);
+ g2d.dispose();
+ return image;
+ }
+
+ private static void validate(BufferedImage bi, BufferedImage goldbi)
+ throws IOException {
+ for (int x = 0; x < bi.getWidth(); ++x) {
+ for (int y = 0; y < bi.getHeight(); ++y) {
+ if (goldbi.getRGB(x, y) != bi.getRGB(x, y)) {
+ ImageIO.write(bi, "png", new File("actual.png"));
+ ImageIO.write(goldbi, "png", new File("expected.png"));
+ throw new RuntimeException("Test failed.");
+ }
+ }
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/awt/image/DrawImage/IncorrectUnmanagedImageSourceOffset.java Tue Oct 28 17:17:05 2014 -0400
@@ -0,0 +1,150 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.awt.AlphaComposite;
+import java.awt.Color;
+import java.awt.Graphics2D;
+import java.awt.GraphicsConfiguration;
+import java.awt.GraphicsEnvironment;
+import java.awt.Image;
+import java.awt.image.BufferedImage;
+import java.awt.image.DataBuffer;
+import java.awt.image.DataBufferByte;
+import java.awt.image.DataBufferInt;
+import java.awt.image.DataBufferShort;
+import java.awt.image.VolatileImage;
+import java.io.File;
+import java.io.IOException;
+
+import javax.imageio.ImageIO;
+
+import static java.awt.Transparency.*;
+import static java.awt.image.BufferedImage.*;
+
+/**
+ * @test
+ * @bug 8029253
+ * @summary Tests asymmetric source offsets when unmanaged image is drawn to VI.
+ * Results of the blit to compatibleImage are used for comparison.
+ * @author Sergey Bylokhov
+ */
+public final class IncorrectUnmanagedImageSourceOffset {
+
+ private static final int[] TYPES = {TYPE_INT_RGB, TYPE_INT_ARGB,
+ TYPE_INT_ARGB_PRE, TYPE_INT_BGR,
+ TYPE_3BYTE_BGR, TYPE_4BYTE_ABGR,
+ TYPE_4BYTE_ABGR_PRE,
+ /*TYPE_USHORT_565_RGB,
+ TYPE_USHORT_555_RGB, TYPE_BYTE_GRAY,
+ TYPE_USHORT_GRAY,*/ TYPE_BYTE_BINARY,
+ TYPE_BYTE_INDEXED};
+ private static final int[] TRANSPARENCIES = {OPAQUE, BITMASK, TRANSLUCENT};
+
+ public static void main(final String[] args) throws IOException {
+ for (final int viType : TRANSPARENCIES) {
+ for (final int biType : TYPES) {
+ BufferedImage bi = makeUnmanagedBI(biType);
+ fill(bi);
+ test(bi, viType);
+ }
+ }
+ }
+
+ private static void test(BufferedImage bi, int type)
+ throws IOException {
+ GraphicsEnvironment ge = GraphicsEnvironment
+ .getLocalGraphicsEnvironment();
+ GraphicsConfiguration gc = ge.getDefaultScreenDevice()
+ .getDefaultConfiguration();
+ VolatileImage vi = gc.createCompatibleVolatileImage(511, 255, type);
+ BufferedImage gold = gc.createCompatibleImage(511, 255, type);
+ // draw to compatible Image
+ Graphics2D big = gold.createGraphics();
+ // force scaled blit
+ big.drawImage(bi, 7, 11, 127, 111, 7, 11, 127 * 2, 111, null);
+ big.dispose();
+ // draw to volatile image
+ BufferedImage snapshot;
+ while (true) {
+ vi.validate(gc);
+ if (vi.validate(gc) != VolatileImage.IMAGE_OK) {
+ try {
+ Thread.sleep(100);
+ } catch (final InterruptedException ignored) {
+ }
+ continue;
+ }
+ Graphics2D vig = vi.createGraphics();
+ // force scaled blit
+ vig.drawImage(bi, 7, 11, 127, 111, 7, 11, 127 * 2, 111, null);
+ vig.dispose();
+ snapshot = vi.getSnapshot();
+ if (vi.contentsLost()) {
+ try {
+ Thread.sleep(100);
+ } catch (final InterruptedException ignored) {
+ }
+ continue;
+ }
+ break;
+ }
+ // validate images
+ for (int x = 7; x < 127; ++x) {
+ for (int y = 11; y < 111; ++y) {
+ if (gold.getRGB(x, y) != snapshot.getRGB(x, y)) {
+ ImageIO.write(gold, "png", new File("gold.png"));
+ ImageIO.write(snapshot, "png", new File("bi.png"));
+ throw new RuntimeException("Test failed.");
+ }
+ }
+ }
+ }
+
+ private static BufferedImage makeUnmanagedBI(final int type) {
+ final BufferedImage bi = new BufferedImage(511, 255, type);
+ final DataBuffer db = bi.getRaster().getDataBuffer();
+ if (db instanceof DataBufferInt) {
+ ((DataBufferInt) db).getData();
+ } else if (db instanceof DataBufferShort) {
+ ((DataBufferShort) db).getData();
+ } else if (db instanceof DataBufferByte) {
+ ((DataBufferByte) db).getData();
+ } else {
+ try {
+ bi.setAccelerationPriority(0.0f);
+ } catch (final Throwable ignored) {
+ }
+ }
+ return bi;
+ }
+
+ private static void fill(final Image image) {
+ final Graphics2D graphics = (Graphics2D) image.getGraphics();
+ graphics.setComposite(AlphaComposite.Src);
+ for (int i = 0; i < image.getHeight(null); ++i) {
+ graphics.setColor(new Color(i, 0, 0));
+ graphics.fillRect(0, i, image.getWidth(null), 1);
+ }
+ graphics.dispose();
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/awt/image/DrawImage/UnmanagedDrawImagePerformance.java Tue Oct 28 17:17:05 2014 -0400
@@ -0,0 +1,125 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.awt.AlphaComposite;
+import java.awt.Graphics2D;
+import java.awt.GraphicsConfiguration;
+import java.awt.GraphicsDevice;
+import java.awt.GraphicsEnvironment;
+import java.awt.Image;
+import java.awt.Polygon;
+import java.awt.geom.AffineTransform;
+import java.awt.image.BufferedImage;
+import java.awt.image.DataBuffer;
+import java.awt.image.DataBufferByte;
+import java.awt.image.DataBufferInt;
+import java.awt.image.DataBufferShort;
+import java.awt.image.VolatileImage;
+
+import static java.awt.Transparency.*;
+import static java.awt.image.BufferedImage.*;
+
+/*
+ * @test
+ * @bug 8029253
+ * @summary Unmanaged images should be drawn fast.
+ * @author Sergey Bylokhov
+ */
+public final class UnmanagedDrawImagePerformance {
+
+ private static final int[] TYPES = {TYPE_INT_RGB, TYPE_INT_ARGB,
+ TYPE_INT_ARGB_PRE, TYPE_INT_BGR,
+ TYPE_3BYTE_BGR, TYPE_4BYTE_ABGR,
+ TYPE_4BYTE_ABGR_PRE,
+ TYPE_USHORT_565_RGB,
+ TYPE_USHORT_555_RGB, TYPE_BYTE_GRAY,
+ TYPE_USHORT_GRAY, TYPE_BYTE_BINARY,
+ TYPE_BYTE_INDEXED};
+ private static final int[] TRANSPARENCIES = {OPAQUE, BITMASK, TRANSLUCENT};
+ private static final int SIZE = 1000;
+ private static final AffineTransform[] TRANSFORMS = {
+ AffineTransform.getScaleInstance(.5, .5),
+ AffineTransform.getScaleInstance(1, 1),
+ AffineTransform.getScaleInstance(2, 2),
+ AffineTransform.getShearInstance(7, 11)};
+
+ public static void main(final String[] args) {
+ for (final AffineTransform atfm : TRANSFORMS) {
+ for (final int viType : TRANSPARENCIES) {
+ for (final int biType : TYPES) {
+ final BufferedImage bi = makeUnmanagedBI(biType);
+ final VolatileImage vi = makeVI(viType);
+ final long time = test(bi, vi, atfm) / 1000000000;
+ if (time > 1) {
+ throw new RuntimeException(String.format(
+ "drawImage is slow: %d seconds", time));
+ }
+ }
+ }
+ }
+ }
+
+ private static long test(Image bi, Image vi, AffineTransform atfm) {
+ final Polygon p = new Polygon();
+ p.addPoint(0, 0);
+ p.addPoint(SIZE, 0);
+ p.addPoint(0, SIZE);
+ p.addPoint(SIZE, SIZE);
+ p.addPoint(0, 0);
+ Graphics2D g2d = (Graphics2D) vi.getGraphics();
+ g2d.clip(p);
+ g2d.transform(atfm);
+ g2d.setComposite(AlphaComposite.SrcOver);
+ final long start = System.nanoTime();
+ g2d.drawImage(bi, 0, 0, null);
+ final long time = System.nanoTime() - start;
+ g2d.dispose();
+ return time;
+ }
+
+ private static VolatileImage makeVI(final int type) {
+ final GraphicsEnvironment ge = GraphicsEnvironment
+ .getLocalGraphicsEnvironment();
+ final GraphicsDevice gd = ge.getDefaultScreenDevice();
+ final GraphicsConfiguration gc = gd.getDefaultConfiguration();
+ return gc.createCompatibleVolatileImage(SIZE, SIZE, type);
+ }
+
+ private static BufferedImage makeUnmanagedBI(final int type) {
+ final BufferedImage img = new BufferedImage(SIZE, SIZE, type);
+ final DataBuffer db = img.getRaster().getDataBuffer();
+ if (db instanceof DataBufferInt) {
+ ((DataBufferInt) db).getData();
+ } else if (db instanceof DataBufferShort) {
+ ((DataBufferShort) db).getData();
+ } else if (db instanceof DataBufferByte) {
+ ((DataBufferByte) db).getData();
+ } else {
+ try {
+ img.setAccelerationPriority(0.0f);
+ } catch (final Throwable ignored) {
+ }
+ }
+ return img;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/awt/print/PrinterJob/ImagePrinting/NullClipARGB.java Tue Oct 28 17:17:05 2014 -0400
@@ -0,0 +1,74 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * @test
+ * @bug 8061392
+ * @summary Test no NPE when printing transparency with null clip.
+ */
+
+import java.awt.*;
+import java.awt.image.*;
+import java.awt.print.*;
+
+public class NullClipARGB implements Printable {
+
+ public static void main( String[] args ) {
+
+ try {
+ PrinterJob pj = PrinterJob.getPrinterJob();
+ pj.setPrintable(new NullClipARGB());
+ pj.print();
+ } catch (Exception ex) {
+ throw new RuntimeException(ex);
+ }
+ }
+
+ public int print(Graphics g, PageFormat pf, int pageIndex)
+ throws PrinterException{
+
+ if (pageIndex != 0) {
+ return NO_SUCH_PAGE;
+ }
+ Graphics2D g2 = (Graphics2D)g;
+ System.out.println("original clip="+g2.getClip());
+ g2.translate(pf.getImageableX(), pf.getImageableY());
+ g2.rotate(0.2);
+ g2.setClip(null);
+ g2.setColor( Color.BLACK );
+ g2.drawString("This text should be visible through the image", 0, 20);
+ BufferedImage bi = new BufferedImage(100, 100,
+ BufferedImage.TYPE_INT_ARGB );
+ Graphics ig = bi.createGraphics();
+ ig.setColor( new Color( 192, 192, 192, 80 ) );
+ ig.fillRect( 0, 0, 100, 100 );
+ ig.setColor( Color.BLACK );
+ ig.drawRect( 0, 0, 99, 99 );
+ ig.dispose();
+ g2.drawImage(bi, 10, 0, 90, 90, null );
+ g2.translate(100, 100);
+ g2.drawString("This text should also be visible through the image", 0, 20);
+ g2.drawImage(bi, 10, 0, 90, 90, null );
+ return PAGE_EXISTS;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/awt/print/PrinterJob/PageRangesDlgTest.java Tue Oct 28 17:17:05 2014 -0400
@@ -0,0 +1,84 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * @test
+ * @bug 8061267
+ * @summary The specified page range should be displayed in the dialog
+ * @run main/manual=yesno PageRangesDlgTest
+ */
+
+import javax.print.*;
+import javax.print.attribute.*;
+import javax.print.attribute.standard.*;
+import java.awt.*;
+import java.awt.print.*;
+
+public class PageRangesDlgTest implements Printable {
+
+ static String[] instr = {
+ "This test is to check that the print dialog displays the specified",
+ "page ranges. You must have a printer installed for this test.",
+ "It is valid only on dialogs which support page ranges",
+ "In each dialog, check that a page range of 2 to 3 is requested",
+ "Optionally press Print instead of Cancel, and verify that the",
+ "correct number/set of pages is printed",
+ };
+
+ public static void main(String args[]) throws Exception {
+ for (int i=0;i<instr.length;i++) {
+ System.out.println(instr[i]);
+ }
+ PrinterJob job = PrinterJob.getPrinterJob();
+ if (job.getPrintService() == null) {
+ System.out.println("No printers. Test cannot continue.");
+ return;
+ }
+ job.setPrintable(new PageRangesDlgTest());
+ PrintRequestAttributeSet aset = new HashPrintRequestAttributeSet();
+ aset.add(new PageRanges(2,3));
+ if (job.printDialog(aset)) {
+ job.print(aset);
+ }
+
+ job = PrinterJob.getPrinterJob();
+ job.setPrintable(new PageRangesDlgTest());
+ aset.add(DialogTypeSelection.NATIVE);
+ if (job.printDialog()) {
+ job.print();
+ }
+ }
+
+ public int print(Graphics g, PageFormat pf, int pi)
+ throws PrinterException {
+
+ System.out.println("pi="+pi);
+ if (pi >= 5) {
+ return NO_SUCH_PAGE;
+ }
+
+ g.drawString("Page : " + (pi+1), 200, 200);
+
+ return PAGE_EXISTS;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/swing/JLayer/8054543/bug8054543.java Tue Oct 28 17:17:05 2014 -0400
@@ -0,0 +1,71 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+ /*
+ * @test
+ * @summary Setting a border on a JLayer causes an Exceptions
+ * @author Alexander Potochkin
+ * @run main bug8054543
+ */
+
+import javax.swing.*;
+import javax.swing.border.Border;
+import java.awt.*;
+
+public class bug8054543 {
+
+ public bug8054543() {
+ JLayer<JComponent> layer = new JLayer<>();
+ Border border = BorderFactory.createLineBorder(Color.GREEN);
+ JButton view = new JButton("JButton");
+
+ layer.setBorder(border);
+ check(layer.getBorder(), null);
+
+ layer.setBorder(null);
+ check(layer.getBorder(), null);
+
+ layer.setView(view);
+ check(layer.getBorder(), view.getBorder());
+
+ layer.setBorder(border);
+ check(border, view.getBorder());
+
+ layer.setBorder(null);
+ check(layer.getBorder(), view.getBorder());
+ }
+
+ private void check(Object o1, Object o2) {
+ if (o1 != o2) {
+ throw new RuntimeException("Test failed");
+ }
+ }
+
+ public static void main(String... args) throws Exception {
+ SwingUtilities.invokeAndWait(new Runnable() {
+ public void run() {
+ new bug8054543();
+ }
+ });
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/swing/JRadioButton/8033699/bug8033699.java Tue Oct 28 17:17:05 2014 -0400
@@ -0,0 +1,255 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+ /*
+ * @test
+ * @library ../../regtesthelpers
+ * @build Util
+ * @bug 8033699
+ * @summary Incorrect radio button behavior when pressing tab key
+ * @author Vivi An
+ * @run main bug8033699
+ */
+
+import javax.swing.*;
+import javax.swing.event.*;
+import java.awt.event.*;
+import java.awt.*;
+import sun.awt.SunToolkit;
+
+public class bug8033699 {
+ private static Robot robot;
+ private static SunToolkit toolkit;
+
+ private static JButton btnStart;
+ private static ButtonGroup btnGrp;
+ private static JButton btnEnd;
+ private static JButton btnMiddle;
+ private static JRadioButton radioBtn1;
+ private static JRadioButton radioBtn2;
+ private static JRadioButton radioBtn3;
+ private static JRadioButton radioBtnSingle;
+
+ public static void main(String args[]) throws Throwable {
+ SwingUtilities.invokeAndWait(new Runnable() {
+ public void run() {
+ createAndShowGUI();
+ }
+ });
+
+ robot = new Robot();
+ Thread.sleep(100);
+
+ robot.setAutoDelay(100);
+ toolkit = (SunToolkit) Toolkit.getDefaultToolkit();
+
+ // tab key test grouped radio button
+ runTest1();
+
+ // tab key test non-grouped radio button
+ runTest2();
+
+ // shift tab key test grouped and non grouped radio button
+ runTest3();
+
+ // left/up key test in grouped radio button
+ runTest4();
+
+ // down/right key test in grouped radio button
+ runTest5();
+
+ // tab from radio button in group to next component in the middle of button group layout
+ runTest6();
+
+ // tab to radio button in group from component in the middle of button group layout
+ runTest7();
+
+ // down key circle back to first button in grouped radio button
+ runTest8();
+ }
+
+ private static void createAndShowGUI() {
+ JFrame mainFrame = new JFrame("Bug 8033699 - 8 Tests for Grouped/Non Group Radio Buttons");
+
+ btnStart = new JButton("Start");
+ btnEnd = new JButton("End");
+ btnMiddle = new JButton("Middle");
+
+ JPanel box = new JPanel();
+ box.setLayout(new BoxLayout(box, BoxLayout.Y_AXIS));
+ box.setBorder(BorderFactory.createTitledBorder("Grouped Radio Buttons"));
+ radioBtn1 = new JRadioButton("A");
+ radioBtn2 = new JRadioButton("B");
+ radioBtn3 = new JRadioButton("C");
+
+ ButtonGroup btnGrp = new ButtonGroup();
+ btnGrp.add(radioBtn1);
+ btnGrp.add(radioBtn2);
+ btnGrp.add(radioBtn3);
+ radioBtn1.setSelected(true);
+
+ box.add(radioBtn1);
+ box.add(radioBtn2);
+ box.add(btnMiddle);
+ box.add(radioBtn3);
+
+ radioBtnSingle = new JRadioButton("Not Grouped");
+ radioBtnSingle.setSelected(true);
+
+ mainFrame.getContentPane().add(btnStart);
+ mainFrame.getContentPane().add(box);
+ mainFrame.getContentPane().add(radioBtnSingle);
+ mainFrame.getContentPane().add(btnEnd);
+
+ mainFrame.getRootPane().setDefaultButton(btnStart);
+ btnStart.requestFocus();
+
+ mainFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
+ mainFrame.setLayout(new BoxLayout(mainFrame.getContentPane(), BoxLayout.Y_AXIS));
+
+ mainFrame.setSize(300, 300);
+ mainFrame.setLocation(200, 200);
+ mainFrame.setVisible(true);
+ mainFrame.toFront();
+ }
+
+ // Radio button Group as a single component when traversing through tab key
+ private static void runTest1() throws Exception{
+ hitKey(robot, KeyEvent.VK_TAB);
+ hitKey(robot, KeyEvent.VK_TAB);
+
+ SwingUtilities.invokeAndWait(new Runnable() {
+ public void run() {
+ if (KeyboardFocusManager.getCurrentKeyboardFocusManager().getFocusOwner() != radioBtnSingle) {
+ System.out.println("Radio Button Group Go To Next Component through Tab Key failed");
+ throw new RuntimeException("Focus is not on Radio Button Single as Expected");
+ }
+ }
+ });
+ }
+
+ // Non-Grouped Radio button as a single component when traversing through tab key
+ private static void runTest2() throws Exception{
+ hitKey(robot, KeyEvent.VK_TAB);
+ SwingUtilities.invokeAndWait(new Runnable() {
+ public void run() {
+ if (KeyboardFocusManager.getCurrentKeyboardFocusManager().getFocusOwner() != btnEnd) {
+ System.out.println("Non Grouped Radio Button Go To Next Component through Tab Key failed");
+ throw new RuntimeException("Focus is not on Button End as Expected");
+ }
+ }
+ });
+ }
+
+ // Non-Grouped Radio button and Group Radio button as a single component when traversing through shift-tab key
+ private static void runTest3() throws Exception{
+ hitKey(robot, KeyEvent.VK_SHIFT, KeyEvent.VK_TAB);
+ hitKey(robot, KeyEvent.VK_SHIFT, KeyEvent.VK_TAB);
+ SwingUtilities.invokeAndWait(new Runnable() {
+ public void run() {
+ if (KeyboardFocusManager.getCurrentKeyboardFocusManager().getFocusOwner() != radioBtn3) {
+ System.out.println("Radio button Group/Non Grouped Radio Button SHIFT-Tab Key Test failed");
+ throw new RuntimeException("Focus is not on Radio Button C as Expected");
+ }
+ }
+ });
+ }
+
+ // Using arrow key to move focus in radio button group
+ private static void runTest4() throws Exception{
+ hitKey(robot, KeyEvent.VK_UP);
+ hitKey(robot, KeyEvent.VK_LEFT);
+ SwingUtilities.invokeAndWait(new Runnable() {
+ public void run() {
+ if (KeyboardFocusManager.getCurrentKeyboardFocusManager().getFocusOwner() != radioBtn1) {
+ System.out.println("Radio button Group UP/LEFT Arrow Key Move Focus Failed");
+ throw new RuntimeException("Focus is not on Radio Button A as Expected");
+ }
+ }
+ });
+ }
+
+ private static void runTest5() throws Exception{
+ hitKey(robot, KeyEvent.VK_DOWN);
+ hitKey(robot, KeyEvent.VK_RIGHT);
+ SwingUtilities.invokeAndWait(new Runnable() {
+ public void run() {
+ if (KeyboardFocusManager.getCurrentKeyboardFocusManager().getFocusOwner() != radioBtn3) {
+ System.out.println("Radio button Group Left/Up Arrow Key Move Focus Failed");
+ throw new RuntimeException("Focus is not on Radio Button C as Expected");
+ }
+ }
+ });
+ }
+
+ private static void runTest6() throws Exception{
+ hitKey(robot, KeyEvent.VK_DOWN);
+ hitKey(robot, KeyEvent.VK_DOWN);
+ SwingUtilities.invokeAndWait(new Runnable() {
+ public void run() {
+ if (KeyboardFocusManager.getCurrentKeyboardFocusManager().getFocusOwner() != radioBtn2) {
+ System.out.println("Radio button Group Circle Back To First Button Test");
+ throw new RuntimeException("Focus is not on Radio Button A as Expected");
+ }
+ }
+ });
+ }
+
+ private static void runTest7() throws Exception{
+ hitKey(robot, KeyEvent.VK_TAB);
+ SwingUtilities.invokeAndWait(new Runnable() {
+ public void run() {
+ if (KeyboardFocusManager.getCurrentKeyboardFocusManager().getFocusOwner() != btnMiddle) {
+ System.out.println("Separate Component added in button group layout");
+ throw new RuntimeException("Focus is not on Middle Button as Expected");
+ }
+ }
+ });
+ }
+
+ private static void runTest8() throws Exception{
+ hitKey(robot, KeyEvent.VK_TAB);
+ SwingUtilities.invokeAndWait(new Runnable() {
+ public void run() {
+ if (KeyboardFocusManager.getCurrentKeyboardFocusManager().getFocusOwner() != radioBtn3) {
+ System.out.println("Separate Component added in button group layout");
+ throw new RuntimeException("Focus is not on Radio Button C as Expected");
+ }
+ }
+ });
+ }
+
+ private static void hitKey(Robot robot, int keycode) {
+ robot.keyPress(keycode);
+ robot.keyRelease(keycode);
+ toolkit.realSync();
+ }
+
+ private static void hitKey(Robot robot, int mode, int keycode) {
+ robot.keyPress(mode);
+ robot.keyPress(keycode);
+ robot.keyRelease(mode);
+ robot.keyRelease(keycode);
+ toolkit.realSync();
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/swing/JTabbedPane/7170310/bug7170310.java Tue Oct 28 17:17:05 2014 -0400
@@ -0,0 +1,124 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.awt.Component;
+import java.awt.Dimension;
+import java.awt.Rectangle;
+import java.awt.Toolkit;
+import javax.swing.JComponent;
+import javax.swing.JFrame;
+import javax.swing.JPanel;
+import javax.swing.JTabbedPane;
+import javax.swing.JViewport;
+import javax.swing.SwingUtilities;
+import javax.swing.UIManager;
+import javax.swing.plaf.metal.MetalLookAndFeel;
+
+import sun.awt.SunToolkit;
+
+/**
+ * @test
+ * @bug 7170310
+ * @author Alexey Ivanov
+ * @summary Selected tab should be scrolled into view.
+ * @run main bug7170310
+ */
+public class bug7170310 {
+ private static final int TABS_NUMBER = 3;
+
+ private static volatile JTabbedPane tabbedPane;
+ private static volatile int count = 1;
+
+ private static volatile JFrame frame;
+
+ private static volatile Exception exception = null;
+
+ public static void main(String[] args) throws Exception {
+ try {
+ UIManager.setLookAndFeel(new MetalLookAndFeel());
+ SwingUtilities.invokeAndWait(bug7170310::createAndShowUI);
+
+ SunToolkit toolkit = (SunToolkit) Toolkit.getDefaultToolkit();
+ toolkit.realSync();
+
+ for (int i = 0; i < TABS_NUMBER; i++) {
+ SwingUtilities.invokeAndWait(bug7170310::addTab);
+ toolkit.realSync();
+ }
+
+ SwingUtilities.invokeAndWait(bug7170310::check);
+
+ if (exception != null) {
+ System.out.println("Test failed: " + exception.getMessage());
+ throw exception;
+ } else {
+ System.out.printf("Test passed");
+ }
+ } finally {
+ frame.dispose();
+ }
+ }
+
+ private static void createAndShowUI() {
+ frame = new JFrame("bug7170310");
+ frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
+ frame.setSize(200, 100);
+
+ tabbedPane = new JTabbedPane();
+ tabbedPane.addTab("Main Tab", new JPanel());
+
+ tabbedPane.setTabLayoutPolicy(JTabbedPane.SCROLL_TAB_LAYOUT);
+
+ frame.getContentPane().add(tabbedPane);
+ frame.setVisible(true);
+ }
+
+ private static void addTab() {
+ tabbedPane.addTab("Added Tab " + count++, new JPanel());
+ tabbedPane.setSelectedIndex(tabbedPane.getTabCount() - 1);
+ }
+
+ private static void check() {
+ try {
+ JViewport vp = null;
+ for (Component c : tabbedPane.getComponents()) {
+ if (c instanceof JViewport) {
+ vp = (JViewport) c;
+ break;
+ }
+ }
+
+ JComponent v = (JComponent) vp.getView();
+ Rectangle vr = vp.getViewRect();
+ Dimension vs = v.getSize();
+
+ // The tab view must be scrolled to the end so that the last tab is visible
+ if (vs.width != (vr.x + vr.width)) {
+ throw new RuntimeException("tabScroller.tabPanel view is positioned incorrectly: "
+ + vs.width + " vs " + (vr.x + vr.width));
+ }
+ } catch (Exception e) {
+ exception = e;
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/swing/text/html/HTMLDocument/8058120/bug8058120.java Tue Oct 28 17:17:05 2014 -0400
@@ -0,0 +1,109 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/* @test
+ * @bug 8058120
+ * @summary Rendering / caret errors with HTMLDocument
+ * @author Dmitry Markov
+ * @run main bug8058120
+ */
+
+import sun.awt.SunToolkit;
+
+import javax.swing.*;
+import javax.swing.text.Element;
+import javax.swing.text.html.HTML;
+import javax.swing.text.html.HTMLDocument;
+import javax.swing.text.html.HTMLEditorKit;
+import java.awt.*;
+
+public class bug8058120 {
+ private static SunToolkit toolkit = (SunToolkit) Toolkit.getDefaultToolkit();
+ private static HTMLDocument document = null;
+ private static final String text = "<p id = 'ab'>ab</p>";
+ private static final String textToInsert = "c";
+
+ public static void main(String[] args) {
+ SwingUtilities.invokeLater(new Runnable() {
+ @Override
+ public void run() {
+ createAndShowGUI();
+ }
+ });
+
+ toolkit.realSync();
+
+ SwingUtilities.invokeLater(new Runnable() {
+ @Override
+ public void run() {
+ try {
+ document.insertAfterEnd(document.getElement("ab"), textToInsert);
+ } catch (Exception ex) {
+ throw new RuntimeException(ex);
+ }
+ }
+ });
+
+ toolkit.realSync();
+
+ SwingUtilities.invokeLater(new Runnable() {
+ @Override
+ public void run() {
+ Element parent = document.getElement("ab").getParentElement();
+ int count = parent.getElementCount();
+ if (count != 2) {
+ throw new RuntimeException("Test Failed! Unexpected Element count = "+count);
+ }
+ Element insertedElement = parent.getElement(count - 1);
+ if (!HTML.Tag.IMPLIED.toString().equals(insertedElement.getName())) {
+ throw new RuntimeException("Test Failed! Inserted text is not wrapped by " + HTML.Tag.IMPLIED + " tag");
+ }
+ }
+ });
+ }
+
+ private static void createAndShowGUI() {
+ try {
+ UIManager.setLookAndFeel("javax.swing.plaf.metal.MetalLookAndFeel");
+ } catch (Exception ex) {
+ throw new RuntimeException(ex);
+ }
+
+ JFrame frame = new JFrame("bug8058120");
+ frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
+
+ JEditorPane editorPane = new JEditorPane();
+ editorPane.setContentType("text/html");
+ editorPane.setEditorKit(new HTMLEditorKit());
+
+ document = (HTMLDocument) editorPane.getDocument();
+
+ editorPane.setText(text);
+
+ frame.add(editorPane);
+ frame.setSize(200, 200);
+ frame.setVisible(true);
+ }
+}
+
+
--- a/jdk/test/sun/java2d/DirectX/OnScreenRenderingResizeTest/OnScreenRenderingResizeTest.java Tue Oct 28 11:29:59 2014 -0400
+++ b/jdk/test/sun/java2d/DirectX/OnScreenRenderingResizeTest/OnScreenRenderingResizeTest.java Tue Oct 28 17:17:05 2014 -0400
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2007, 2014, Oracle and/or its affiliates. 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
@@ -89,8 +89,13 @@
public void update(Graphics g) {}
};
frame.setBackground(bgColor);
+ frame.setUndecorated(true);
frame.pack();
- frame.setSize(FRAME_W, FRAME_H);
+
+ GraphicsConfiguration gc = frame.getGraphicsConfiguration();
+ Rectangle gcBounds = gc.getBounds();
+ frame.setBounds(gcBounds.width / 4, gcBounds.height / 4, FRAME_W, FRAME_H);
+
frame.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
done = true;
@@ -108,9 +113,8 @@
ex.printStackTrace();
}
- GraphicsConfiguration gc = frame.getGraphicsConfiguration();
- int maxW = gc.getBounds().width /2;
- int maxH = gc.getBounds().height/2;
+ int maxW = gcBounds.width /2;
+ int maxH = gcBounds.height/2;
int minW = frame.getWidth();
int minH = frame.getHeight();
int incW = 10, incH = 10, cnt = 0;
@@ -155,6 +159,7 @@
Insets in = frame.getInsets();
frame.getGraphics().drawImage(output, in.left, in.top, null);
if (cnt == 90 && robot != null) {
+ robot.waitForIdle();
// area where we blitted to should be either white or green
Point p = frame.getLocationOnScreen();
p.translate(in.left+10, in.top+10);
@@ -172,7 +177,7 @@
frame.getWidth()-in.left-in.right,
frame.getHeight()-in.top-in.bottom-5-IMAGE_H));
int accepted2[] = { Color.white.getRGB() };
- checkBI(bi, accepted1);
+ checkBI(bi, accepted2);
}
Thread.yield();