Merge
authorlana
Mon, 04 Apr 2011 17:18:35 -0700
changeset 8952 86329089fca0
parent 8946 4d0bfa0b8899 (current diff)
parent 8951 5c8029a3c2e1 (diff)
child 8990 7b24333cc9bf
Merge
--- a/jdk/make/sun/xawt/mapfile-vers	Fri Apr 01 23:55:08 2011 -0700
+++ b/jdk/make/sun/xawt/mapfile-vers	Mon Apr 04 17:18:35 2011 -0700
@@ -158,6 +158,7 @@
         Java_sun_awt_X11_XRobotPeer_mouseReleaseImpl;
         Java_sun_awt_X11_XRobotPeer_mouseWheelImpl;
         Java_sun_awt_X11_XRobotPeer_setup;
+        Java_sun_awt_X11_XRobotPeer__1dispose;
         Java_sun_awt_X11_XToolkit_getNumberOfButtonsImpl;
         Java_java_awt_Component_initIDs;
         Java_java_awt_Container_initIDs;
--- a/jdk/src/share/classes/java/awt/Toolkit.java	Fri Apr 01 23:55:08 2011 -0700
+++ b/jdk/src/share/classes/java/awt/Toolkit.java	Mon Apr 04 17:18:35 2011 -0700
@@ -1157,12 +1157,9 @@
      *          takes JobAttributes and PageAttributes objects. This object
      *          may be updated to reflect the user's job choices on exit. May
      *          be null.
-     *
      * @return  a <code>PrintJob</code> object, or <code>null</code> if the
      *          user cancelled the print job.
-     * @throws  NullPointerException if frame is null.  This exception is
-     *          always thrown when GraphicsEnvironment.isHeadless() returns
-     *          true.
+     * @throws  NullPointerException if frame is null
      * @throws  SecurityException if this thread is not allowed to initiate a
      *          print job request
      * @see     java.awt.GraphicsEnvironment#isHeadless
@@ -1201,12 +1198,9 @@
      *          job. The attributes will be updated to reflect the user's
      *          choices as outlined in the PageAttributes documentation. May be
      *          null.
-     *
      * @return  a <code>PrintJob</code> object, or <code>null</code> if the
      *          user cancelled the print job.
-     * @throws  NullPointerException if frame is null and either jobAttributes
-     *          is null or jobAttributes.getDialog() returns
-     *          JobAttributes.DialogType.NATIVE.
+     * @throws  NullPointerException if frame is null
      * @throws  IllegalArgumentException if pageAttributes specifies differing
      *          cross feed and feed resolutions. Also if this thread has
      *          access to the file system and jobAttributes specifies
@@ -1218,9 +1212,6 @@
      *          opportunity to select a file and proceed with printing.
      *          The dialog will ensure that the selected output file
      *          is valid before returning from this method.
-     *          <p>
-     *          This exception is always thrown when GraphicsEnvironment.isHeadless()
-     *          returns true.
      * @throws  SecurityException if this thread is not allowed to initiate a
      *          print job request, or if jobAttributes specifies print to file,
      *          and this thread is not allowed to access the file system
@@ -1236,10 +1227,6 @@
                                 PageAttributes pageAttributes) {
         // Override to add printing support with new job/page control classes
 
-        if (GraphicsEnvironment.isHeadless()) {
-            throw new IllegalArgumentException();
-        }
-
         if (this != Toolkit.getDefaultToolkit()) {
             return Toolkit.getDefaultToolkit().getPrintJob(frame, jobtitle,
                                                            jobAttributes,
--- a/jdk/src/share/classes/sun/awt/HeadlessToolkit.java	Fri Apr 01 23:55:08 2011 -0700
+++ b/jdk/src/share/classes/sun/awt/HeadlessToolkit.java	Mon Apr 04 17:18:35 2011 -0700
@@ -320,8 +320,7 @@
             // Should never happen
             throw new HeadlessException();
         }
-        throw new IllegalArgumentException(
-                "PrintJob not supported in a headless environment");
+        throw new NullPointerException("frame must not be null");
     }
 
     public PrintJob getPrintJob(Frame frame, String doctitle, Properties props)
@@ -330,8 +329,7 @@
             // Should never happen
             throw new HeadlessException();
         }
-        throw new IllegalArgumentException(
-                "PrintJob not supported in a headless environment");
+        throw new NullPointerException("frame must not be null");
     }
 
     /*
--- a/jdk/src/solaris/classes/sun/awt/X11/XRobotPeer.java	Fri Apr 01 23:55:08 2011 -0700
+++ b/jdk/src/solaris/classes/sun/awt/X11/XRobotPeer.java	Mon Apr 04 17:18:35 2011 -0700
@@ -48,7 +48,7 @@
     }
 
     public void dispose() {
-        // does nothing
+        _dispose();
     }
 
     public void mouseMove(int x, int y) {
@@ -88,6 +88,7 @@
     }
 
     private static native synchronized void setup(int numberOfButtons, int[] buttonDownMasks);
+    private static native synchronized void _dispose();
 
     private static native synchronized void mouseMoveImpl(X11GraphicsConfig xgc, int x, int y);
     private static native synchronized void mousePressImpl(int buttons);
--- a/jdk/src/solaris/classes/sun/awt/X11/XToolkit.java	Fri Apr 01 23:55:08 2011 -0700
+++ b/jdk/src/solaris/classes/sun/awt/X11/XToolkit.java	Mon Apr 04 17:18:35 2011 -0700
@@ -1222,8 +1222,8 @@
     public PrintJob getPrintJob(final Frame frame, final String doctitle,
                                 final Properties props) {
 
-        if (GraphicsEnvironment.isHeadless()) {
-            throw new IllegalArgumentException();
+        if (frame == null) {
+            throw new NullPointerException("frame must not be null");
         }
 
         PrintJob2D printJob = new PrintJob2D(frame, doctitle, props);
@@ -1236,11 +1236,10 @@
 
     public PrintJob getPrintJob(final Frame frame, final String doctitle,
                 final JobAttributes jobAttributes,
-                final PageAttributes pageAttributes) {
-
-
-        if (GraphicsEnvironment.isHeadless()) {
-            throw new IllegalArgumentException();
+                final PageAttributes pageAttributes)
+    {
+        if (frame == null) {
+            throw new NullPointerException("frame must not be null");
         }
 
         PrintJob2D printJob = new PrintJob2D(frame, doctitle,
--- a/jdk/src/solaris/native/sun/awt/awt_Robot.c	Fri Apr 01 23:55:08 2011 -0700
+++ b/jdk/src/solaris/native/sun/awt/awt_Robot.c	Mon Apr 04 17:18:35 2011 -0700
@@ -48,12 +48,28 @@
 #ifdef __linux__
 #include <sys/socket.h>
 #endif
+#include <dlfcn.h>
 
 extern struct X11GraphicsConfigIDs x11GraphicsConfigIDs;
 
 static jint * masks;
 static jint num_buttons;
 
+static unsigned int s_robotInstanceCounter = 0;
+
+static void* xcompositeLibHandle = NULL;
+static Bool xcompositeExtAvailable = False;
+static Bool xcompositeExtTested = False;
+
+typedef Status (*T_XCompositeQueryVersion)(Display *dpy, int *major_versionp, int *minor_versionp);
+typedef Window (*T_XCompositeGetOverlayWindow)(Display *dpy, Window window);
+typedef void (*T_XCompositeReleaseOverlayWindow)(Display *dpy, Window window);
+
+static T_XCompositeQueryVersion XCompositeQueryVersion = NULL;
+static T_XCompositeGetOverlayWindow XCompositeGetOverlayWindow = NULL;
+static T_XCompositeReleaseOverlayWindow XCompositeReleaseOverlayWindow = NULL;
+
+
 static int32_t isXTestAvailable() {
     int32_t major_opcode, first_event, first_error;
     int32_t  event_basep, error_basep, majorp, minorp;
@@ -194,8 +210,80 @@
     }
 
     AWT_UNLOCK();
+
+    s_robotInstanceCounter++;
+}
+
+JNIEXPORT void JNICALL
+Java_sun_awt_X11_XRobotPeer__1dispose (JNIEnv * env, jclass cls)
+{
+    if (--s_robotInstanceCounter) {
+        return;
+    }
+
+    // This is the last instance of the XRobotPeer being released
+
+    if (xcompositeExtTested && xcompositeExtAvailable && xcompositeLibHandle) {
+        // The lib is loaded in IsXCompositeAvailable(). Unload under AWT_LOCK
+        // so that the shutdown function of the lib behaves correctly.
+        AWT_LOCK();
+        dlclose(xcompositeLibHandle);
+        AWT_UNLOCK();
+    }
+
+    xcompositeExtTested = False;
+    xcompositeExtAvailable = False;
+    xcompositeLibHandle = NULL;
 }
 
+/*
+ * Returns True only if XCOMPOSITE is of version 0.3 or higher.
+ * The functions that we need are available since that version.
+ *
+ * Must be invoked under AWT_LOCK.
+ *
+ * Leaves the library loaded if the version is correct.
+ */
+static Bool IsXCompositeAvailable()
+{
+    if (!xcompositeExtTested) {
+        int opcode, eventb, errorb;
+
+        if (XQueryExtension(awt_display, "Composite", &opcode, &eventb, &errorb)) {
+            xcompositeLibHandle = dlopen("libXcomposite.so.1", RTLD_LAZY | RTLD_GLOBAL);
+#ifndef __linux__ /* SOLARIS */
+            if (xcompositeLibHandle == NULL) {
+                xcompositeLibHandle = dlopen("/usr/sfw/lib/libXcomposite.so.1",
+                        RTLD_LAZY | RTLD_GLOBAL);
+            }
+#endif
+
+            if (xcompositeLibHandle) {
+                int major, minor;
+                XCompositeQueryVersion = (T_XCompositeQueryVersion)dlsym(xcompositeLibHandle, "XCompositeQueryVersion");
+
+                if (XCompositeQueryVersion && XCompositeQueryVersion(awt_display, &major, &minor)) {
+                    if (major >= 0 && minor >= 3) {
+                        XCompositeGetOverlayWindow = (T_XCompositeGetOverlayWindow)dlsym(xcompositeLibHandle, "XCompositeGetOverlayWindow");
+                        XCompositeReleaseOverlayWindow = (T_XCompositeReleaseOverlayWindow)dlsym(xcompositeLibHandle, "XCompositeReleaseOverlayWindow");
+
+                        if (XCompositeGetOverlayWindow && XCompositeReleaseOverlayWindow) {
+                            xcompositeExtAvailable = True;
+                        }
+                    }
+                }
+
+                if (!xcompositeExtAvailable) {
+                    dlclose(xcompositeLibHandle);
+                } /* else the lib is unloaded in _dispose() */
+            }
+        }
+
+        xcompositeExtTested = True;
+    }
+
+    return xcompositeExtAvailable;
+}
 
 JNIEXPORT void JNICALL
 Java_sun_awt_X11_XRobotPeer_getRGBPixelsImpl( JNIEnv *env,
@@ -211,7 +299,7 @@
     jint *ary;               /* Array of jints for sending pixel values back
                               * to parent process.
                               */
-    Window rootWindow;
+    Window window;
     AwtGraphicsConfigDataPtr adata;
 
     DTRACE_PRINTLN6("RobotPeer: getRGBPixelsImpl(%lx, %d, %d, %d, %d, %x)", xgc, x, y, width, height, pixelArray);
@@ -228,14 +316,24 @@
     adata = (AwtGraphicsConfigDataPtr) JNU_GetLongFieldAsPtr(env, xgc, x11GraphicsConfigIDs.aData);
     DASSERT(adata != NULL);
 
-    rootWindow = XRootWindow(awt_display, adata->awt_visInfo.screen);
-    image = getWindowImage(awt_display, rootWindow, x, y, width, height);
+    window = XRootWindow(awt_display, adata->awt_visInfo.screen);
+
+    if (IsXCompositeAvailable()) {
+        // Use 'composite overlay window' instead of the root window.
+        // See 6903034 for details.
+        window = XCompositeGetOverlayWindow(awt_display, window);
+    }
+
+    image = getWindowImage(awt_display, window, x, y, width, height);
 
     /* Array to use to crunch around the pixel values */
     ary = (jint *) malloc(width * height * sizeof (jint));
     if (ary == NULL) {
         JNU_ThrowOutOfMemoryError(env, "OutOfMemoryError");
         XDestroyImage(image);
+        if (IsXCompositeAvailable()) {
+            XCompositeReleaseOverlayWindow(awt_display, window);
+        }
         AWT_UNLOCK();
         return;
     }
@@ -256,6 +354,9 @@
     free(ary);
 
     XDestroyImage(image);
+    if (IsXCompositeAvailable()) {
+        XCompositeReleaseOverlayWindow(awt_display, window);
+    }
 
     AWT_UNLOCK();
 }
--- a/jdk/src/windows/classes/sun/awt/windows/WToolkit.java	Fri Apr 01 23:55:08 2011 -0700
+++ b/jdk/src/windows/classes/sun/awt/windows/WToolkit.java	Mon Apr 04 17:18:35 2011 -0700
@@ -630,10 +630,10 @@
 
     public PrintJob getPrintJob(Frame frame, String doctitle,
                                 JobAttributes jobAttributes,
-                                PageAttributes pageAttributes) {
-
-        if (GraphicsEnvironment.isHeadless()) {
-            throw new IllegalArgumentException();
+                                PageAttributes pageAttributes)
+    {
+        if (frame == null) {
+            throw new NullPointerException("frame must not be null");
         }
 
         PrintJob2D printJob = new PrintJob2D(frame, doctitle,
--- a/jdk/src/windows/native/sun/windows/awt_Toolkit.cpp	Fri Apr 01 23:55:08 2011 -0700
+++ b/jdk/src/windows/native/sun/windows/awt_Toolkit.cpp	Mon Apr 04 17:18:35 2011 -0700
@@ -528,9 +528,6 @@
 
     tk.m_isActive = FALSE;
 
-    awt_dnd_uninitialize();
-    awt_clipboard_uninitialize((JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2));
-
     // dispose Direct3D-related resources. This should be done
     // before AwtObjectList::Cleanup() as the d3d will attempt to
     // shutdown when the last of its windows is disposed of
@@ -539,6 +536,9 @@
     AwtObjectList::Cleanup();
     AwtFont::Cleanup();
 
+    awt_dnd_uninitialize();
+    awt_clipboard_uninitialize((JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2));
+
     if (tk.m_inputMethodHWnd != NULL) {
         ::SendMessage(tk.m_inputMethodHWnd, WM_IME_CONTROL, IMC_OPENSTATUSWINDOW, 0);
     }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/awt/Toolkit/Headless/GetPrintJob/GetPrintJob.java	Mon Apr 04 17:18:35 2011 -0700
@@ -0,0 +1,48 @@
+/*
+@test
+@bug 7023011
+@library ../../../regtesthelpers
+@build Sysout
+@summary Toolkit.getPrintJob() throws wrong exceptions
+@author andrei dmitriev: area=awt.headless
+@run main GetPrintJob
+ */
+
+import java.awt.*;
+import java.util.Properties;
+import test.java.awt.regtesthelpers.Sysout;
+/*
+ * In headfull mode we should always getting NPE on the getPrintJob() call if frame == null.
+ */
+
+public class GetPrintJob {
+
+    public static void main(String[] s) {
+        boolean stage1Passed = false;
+        boolean stage2Passed = false;
+
+        try {
+            Toolkit.getDefaultToolkit().getPrintJob(
+                    (Frame) null, "title", new Properties());
+        } catch (NullPointerException e) {
+            stage1Passed = true;
+            Sysout.println("Stage 1 passed. getPrintJob(null, String, property) has thrown NPE.");
+        }
+        if (!stage1Passed) {
+            throw new RuntimeException("getPrintJob() should have thrown NPE but didn't.");
+        }
+
+        try {
+            Toolkit.getDefaultToolkit().getPrintJob(
+                    (Frame) null, "title", new JobAttributes(), new PageAttributes());
+        } catch (NullPointerException e) {
+            stage2Passed = true;
+            Sysout.println("Stage 2 passed. getPrintJob(null, String, jobAttrs, pageAttr) has thrown NPE.");
+        }
+        if (!stage2Passed) {
+            throw new RuntimeException("getPrintJob() should have thrown NPE but didn't.");
+        }
+
+        Sysout.println("Test PASSED");
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/awt/Toolkit/Headless/GetPrintJob/GetPrintJobHeadless.java	Mon Apr 04 17:18:35 2011 -0700
@@ -0,0 +1,50 @@
+/*
+@test
+@bug 7023011
+@library ../../../regtesthelpers
+@build Sysout
+@summary Toolkit.getPrintJob() throws wrong exceptions
+@author andrei dmitriev: area=awt.headless
+@run main/othervm -Djava.awt.headless=true GetPrintJobHeadless
+ */
+
+/*
+ * In headless mode we should always getting NPE on the getPrintJob() call
+ */
+import java.awt.*;
+import java.util.Properties;
+import test.java.awt.regtesthelpers.Sysout;
+
+public class GetPrintJobHeadless {
+
+    public static void main(String[] s) {
+        boolean stage1Passed = false;
+        boolean stage2Passed = false;
+
+        try {
+            Toolkit.getDefaultToolkit().getPrintJob(
+                    (Frame) null, "title", new Properties());
+        } catch (NullPointerException e) {
+            stage1Passed = true;
+            e.printStackTrace();
+            Sysout.println("Stage 1 passed. getPrintJob(null, String, property) has thrown NPE.");
+        }
+        if (!stage1Passed) {
+            throw new RuntimeException("getPrintJob() should have thrown NPE but didn't.");
+        }
+
+        try {
+            Toolkit.getDefaultToolkit().getPrintJob(
+                    (Frame) null, "title", new JobAttributes(), new PageAttributes());
+        } catch (NullPointerException e) {
+            stage2Passed = true;
+            e.printStackTrace();
+            Sysout.println("Stage 2 passed. getPrintJob(null, String, jobAttrs, pageAttr) has thrown  NPE.");
+        }
+        if (!stage2Passed) {
+            throw new RuntimeException("getPrintJob() should have thrown NPE but didn't.");
+        }
+
+        Sysout.println("Test PASSED");
+    }
+}