--- /dev/null 2014-04-18 17:39:37.000000000 +0400
+++ new/test/java/awt/dnd/Win32TYMEDSelectionTest/Makefile 2014-04-18 17:39:35.693592100 +0400
@@ -0,0 +1,5 @@
+all: child.cpp
+ cl -o child.exe child.cpp user32.lib ole32.lib gdi32.lib
+
+clean:
+ rm -f child.exe child.obj
--- /dev/null 2014-04-18 17:39:39.000000000 +0400
+++ new/test/java/awt/dnd/Win32TYMEDSelectionTest/Win32TYMEDSelectionTest.html 2014-04-18 17:39:38.578757100 +0400
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+
+Win32TYMEDSelectionTest
Bug ID: 4426805
+
+ This is an AUTOMATIC test, simply wait for completion
+
+
+
+
--- /dev/null 2014-04-18 17:39:41.000000000 +0400
+++ new/test/java/awt/dnd/Win32TYMEDSelectionTest/Win32TYMEDSelectionTest.java 2014-04-18 17:39:40.740880800 +0400
@@ -0,0 +1,193 @@
+/*
+ test
+ @bug 4426805 4427837
+ @summary tests that drag source provides data in the requested tymed
+ in java-to-native drag-and-drop operation on Win32
+ @author das@sparc.spb.su area=dnd
+ @run applet Win32TYMEDSelectionTest.html
+*/
+
+/**
+ * Win32TYMEDSelectionTest.java
+ *
+ * summary: tests that drag source provides data in the requested tymed
+ * in java-to-native drag-and-drop operation on Win32
+ */
+
+import java.applet.Applet;
+import java.awt.*;
+import java.awt.datatransfer.*;
+import java.awt.dnd.*;
+import java.awt.event.*;
+import java.io.*;
+
+
+public class Win32TYMEDSelectionTest extends Applet implements Runnable {
+
+ /*
+ * NOTE: These constants are duplicated in child.cpp.
+ * Be sure to keep them is sync.
+ */
+ public static final int CODE_NOT_RETURNED = -1;
+ public static final int CODE_OK = 0;
+ public static final int CODE_INVALID_TYMED_FAILURE = 1;
+ public static final int CODE_INVALID_DATA_FAILURE = 2;
+ public static final String TEST_TEXT = "TEST TEXT";
+ public static final int X = 300;
+ public static final int Y = 300;
+ public static final int WIDTH = 100;
+ public static final int HEIGHT = 100;
+
+ public static final int ACTIVATION_TIMEOUT = 2000;
+
+ private transient int retCode = CODE_NOT_RETURNED;
+
+ final Frame frame = new Frame();
+ final Button button = new DragSourceButton();
+ private Process process;
+
+ public void run() {
+ try {
+ Thread.sleep(ACTIVATION_TIMEOUT);
+
+ final Point sourcePoint = button.getLocationOnScreen();
+ final Dimension d = button.getSize();
+ sourcePoint.translate(d.width / 2, d.height / 2);
+ final Point targetPoint = new Point(X + WIDTH / 2, Y + HEIGHT / 2);
+
+ final Robot robot = new Robot();
+ robot.mouseMove(sourcePoint.x, sourcePoint.y);
+ robot.keyPress(KeyEvent.VK_CONTROL);
+ robot.mousePress(InputEvent.BUTTON1_MASK);
+ for (;!sourcePoint.equals(targetPoint);
+ sourcePoint.translate(sign(targetPoint.x - sourcePoint.x),
+ sign(targetPoint.y - sourcePoint.y))) {
+
+ robot.mouseMove(sourcePoint.x, sourcePoint.y);
+ Thread.sleep(10);
+ }
+ robot.mouseRelease(InputEvent.BUTTON1_MASK);
+ robot.keyRelease(KeyEvent.VK_CONTROL);
+
+ Thread.sleep(ACTIVATION_TIMEOUT);
+
+ if (retCode == CODE_NOT_RETURNED) {
+ process.destroy();
+ }
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ } // run()
+
+ public static int sign(int n) {
+ return n < 0 ? -1 : n == 0 ? 0 : 1;
+ }
+
+ public void start() {
+
+ if (System.getProperty("os.name").startsWith("Windows")) {
+ frame.setTitle("DragSource frame");
+ frame.setLocation(200, 200);
+ frame.add(button);
+ frame.pack();
+ frame.setVisible(true);
+
+ String testPath = System.getProperty("test.src", ".");
+
+ try {
+ Process process = Runtime.getRuntime().exec("cp " + testPath + File.separator + "child.exe .");
+ process.waitFor();
+ process = Runtime.getRuntime().exec("chmod 755 child.exe");
+ process.waitFor();
+ }catch (InterruptedException ire) {
+ ire.printStackTrace();
+ } catch (IOException ie) {
+ ie.printStackTrace();
+ }
+
+ String command = "./child.exe";
+ try {
+ process = Runtime.getRuntime().exec(command);
+ new Thread(this).start();
+
+ retCode = process.waitFor();
+
+ InputStream errorStream = process.getErrorStream();
+ int count = errorStream.available();
+ if (count > 0) {
+ byte[] b = new byte[count];
+ errorStream.read(b);
+ System.err.println("========= Child VM System.err ========");
+ System.err.print(new String(b));
+ System.err.println("======================================");
+ }
+
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ System.err.println("Child VM: returned: " + retCode);
+ switch (retCode) {
+ case CODE_NOT_RETURNED:
+ System.err.println("Child VM: failed to start");
+ break;
+ case CODE_OK:
+ System.err.println("Child VM: normal termination");
+ break;
+ default:
+ System.err.println("Child VM: other failure");
+ break;
+ case CODE_INVALID_TYMED_FAILURE:
+ System.err.println("Child VM: invalid tymed detected");
+ throw new RuntimeException("The test failed.");
+ case CODE_INVALID_DATA_FAILURE:
+ System.err.println("Child VM: invalid transfer data detected");
+ throw new RuntimeException("The test failed.");
+ }
+ }
+ } // start()
+} // class Win32TYMEDSelectionTest
+
+class DragSourceButton extends Button implements Serializable,
+ DragGestureListener,
+ Transferable {
+ static final DataFlavor[] flavors =
+ new DataFlavor[] { DataFlavor.stringFlavor, DataFlavor.imageFlavor };
+
+ public DragSourceButton() {
+ this("DragSourceButton");
+ }
+
+ public DragSourceButton(String str) {
+ super(str);
+
+ DragSource ds = DragSource.getDefaultDragSource();
+ ds.createDefaultDragGestureRecognizer(this, DnDConstants.ACTION_COPY,
+ this);
+ }
+
+ public void dragGestureRecognized(DragGestureEvent dge) {
+ dge.startDrag(null, this,
+ new DragSourceAdapter() {});
+ }
+
+ public DataFlavor[] getTransferDataFlavors() {
+ return flavors;
+ }
+
+ public boolean isDataFlavorSupported(DataFlavor flavor) {
+ return DataFlavor.stringFlavor.equals(flavor) ||
+ DataFlavor.imageFlavor.equals(flavor);
+ }
+
+ public Object getTransferData(DataFlavor flavor)
+ throws UnsupportedFlavorException, IOException {
+ if (DataFlavor.stringFlavor.equals(flavor)) {
+ return Win32TYMEDSelectionTest.TEST_TEXT;
+ } else if (DataFlavor.imageFlavor.equals(flavor)) {
+ return createImage(10, 10);
+ } else {
+ throw new UnsupportedFlavorException(flavor);
+ }
+ }
+}
+
--- /dev/null 2014-04-18 17:39:43.000000000 +0400
+++ new/test/java/awt/dnd/Win32TYMEDSelectionTest/child.cpp 2014-04-18 17:39:42.898004200 +0400
@@ -0,0 +1,315 @@
+#define STRICT
+#include
+#include
+#include
+
+/*
+ * NOTE: These constants are duplicated in Win32TYMEDSelectionTest.java.
+ * Be sure to keep them is sync.
+ */
+static const int CODE_OK = 0;
+static const int CODE_INVALID_TYMED_FAILURE = 1;
+static const int CODE_INVALID_DATA_FAILURE = 2;
+static const int CODE_OTHER_FAILURE = 3;
+static const char* TEST_TEXT = "TEST TEXT";
+static const int X = 300;
+static const int Y = 300;
+static const int WIDTH = 100;
+static const int HEIGHT = 100;
+
+static const char szClassName[] = "test window";
+
+class TestDropTarget : virtual public IDropTarget {
+ public:
+ TestDropTarget();
+ virtual ~TestDropTarget();
+
+ virtual HRESULT __stdcall QueryInterface(REFIID riid,
+ void __RPC_FAR*__RPC_FAR *ppvObject);
+ virtual ULONG __stdcall AddRef(void);
+ virtual ULONG __stdcall Release(void);
+ virtual HRESULT __stdcall DragEnter(IDataObject __RPC_FAR *pDataObject,
+ DWORD grfKeyState, POINTL pt,
+ DWORD __RPC_FAR *pdwEffect);
+ virtual HRESULT __stdcall DragOver(DWORD grfKeyState, POINTL pt,
+ DWORD __RPC_FAR *pdwEffect);
+ virtual HRESULT __stdcall DragLeave(void);
+ virtual HRESULT __stdcall Drop(IDataObject __RPC_FAR *pDataObject,
+ DWORD grfKeyState, POINTL pt,
+ DWORD __RPC_FAR *pdwEffect);
+ virtual int CheckTransferTymed(IDataObject __RPC_FAR *pDataObj,
+ DWORD tymed);
+ virtual void DumpTestResult(DWORD tymed, int nTestResult);
+ private:
+ unsigned int m_refs;
+};
+
+TestDropTarget::TestDropTarget() {
+ m_refs = 0U;
+ AddRef();
+}
+
+TestDropTarget::~TestDropTarget() {}
+
+HRESULT __stdcall
+TestDropTarget::QueryInterface(REFIID riid,
+ void __RPC_FAR *__RPC_FAR *ppvObject) {
+ if (riid == IID_IUnknown) {
+ *ppvObject = (void __RPC_FAR *__RPC_FAR)(IUnknown*)this;
+ AddRef();
+ return S_OK;
+ } else if (riid == IID_IDropTarget) {
+ *ppvObject = (void __RPC_FAR *__RPC_FAR)(IDropTarget*)this;
+ AddRef();
+ return S_OK;
+ } else {
+ *ppvObject = (void __RPC_FAR *__RPC_FAR)NULL;
+ return E_NOINTERFACE;
+ }
+}
+
+ULONG __stdcall
+TestDropTarget::AddRef() {
+ return (ULONG)++m_refs;
+}
+
+ULONG __stdcall
+TestDropTarget::Release() {
+ int refs;
+ if ((refs = --m_refs) == 0) delete this;
+ return (ULONG)refs;
+}
+
+HRESULT __stdcall
+TestDropTarget::DragEnter(IDataObject __RPC_FAR *pDataObj, DWORD grfKeyState,
+ POINTL pt, DWORD __RPC_FAR *pdwEffect) {
+ *pdwEffect = DROPEFFECT_COPY;
+ return S_OK;
+}
+
+HRESULT __stdcall
+TestDropTarget::DragOver(DWORD grfKeyState, POINTL pt,
+ DWORD __RPC_FAR *pdwEffect) {
+ *pdwEffect = DROPEFFECT_COPY;
+ return S_OK;
+}
+
+HRESULT __stdcall
+TestDropTarget::DragLeave() {
+ return S_OK;
+}
+
+HRESULT __stdcall
+TestDropTarget::Drop(IDataObject __RPC_FAR *pDataObj, DWORD grfKeyState,
+ POINTL pt, DWORD __RPC_FAR *pdwEffect) {
+ int nExitCode = CODE_OTHER_FAILURE;
+ HRESULT res = S_OK;
+
+ *pdwEffect = DROPEFFECT_NONE;
+
+ nExitCode = CheckTransferTymed(pDataObj, TYMED_HGLOBAL);
+ if (nExitCode == CODE_OK) {
+ nExitCode = CheckTransferTymed(pDataObj, TYMED_ISTREAM);
+ }
+ if (nExitCode == CODE_OK) {
+ nExitCode = CheckTransferTymed(pDataObj, TYMED_ENHMF);
+ }
+
+ if (nExitCode == CODE_OK) {
+ *pdwEffect = DROPEFFECT_COPY;
+ }
+ ::PostQuitMessage(nExitCode);
+ return res;
+}
+
+int
+TestDropTarget::CheckTransferTymed(IDataObject __RPC_FAR *pDataObj,
+ DWORD tymed) {
+ int nExitCode = CODE_OTHER_FAILURE;
+ FORMATETC format;
+
+ switch (tymed) {
+ case TYMED_HGLOBAL:
+ case TYMED_ISTREAM:
+ format.cfFormat = CF_TEXT;
+ break;
+ case TYMED_ENHMF:
+ format.cfFormat = CF_ENHMETAFILE;
+ break;
+ }
+ format.ptd = NULL;
+ format.lindex = -1;
+ format.dwAspect = DVASPECT_CONTENT;
+ format.tymed = tymed;
+
+ STGMEDIUM stgmedium;
+
+ HRESULT res = pDataObj->GetData(&format, &stgmedium);
+ if (res == S_OK) {
+ if (stgmedium.tymed == tymed) {
+ nExitCode = CODE_INVALID_DATA_FAILURE;
+
+ switch (tymed) {
+ case TYMED_HGLOBAL: {
+ DWORD size = ::GlobalSize(stgmedium.hGlobal);
+ if (size != 0) {
+ LPVOID data = ::GlobalLock(stgmedium.hGlobal);
+ if (strcmp((const char*)data, TEST_TEXT) == 0) {
+ nExitCode = CODE_OK;
+ }
+ }
+ break;
+ }
+ case TYMED_ISTREAM: {
+ IStream* pstm = stgmedium.pstm;
+ if (pstm != NULL) {
+ STATSTG statstg;
+ if (pstm->Stat(&statstg, STATFLAG_NONAME) == S_OK) {
+ if (statstg.cbSize.LowPart >= strlen(TEST_TEXT) &&
+ statstg.cbSize.HighPart == 0) {
+ ULONG size = (ULONG)statstg.cbSize.QuadPart;
+ ULONG act = 0;
+ LPVOID buf = calloc(1, size);
+ if (buf != NULL) {
+ if (pstm->Read((void*)buf,size,&act) == S_OK &&
+ strcmp((const char*)buf, TEST_TEXT) == 0) {
+
+ nExitCode = CODE_OK;
+ }
+ free(buf);
+ }
+ }
+ }
+ }
+ break;
+ }
+ case TYMED_ENHMF: {
+ HENHMETAFILE hemf = stgmedium.hEnhMetaFile;
+ UINT size = ::GetEnhMetaFileHeader(hemf, 0, NULL);
+ BOOL headerValid = FALSE;
+ if (size != 0) {
+ LPENHMETAHEADER lpemh = (LPENHMETAHEADER)calloc(1, size);
+ if (lpemh != NULL) {
+ if (::GetEnhMetaFileHeader(hemf, size, lpemh) == size) {
+ headerValid = TRUE;
+ }
+ free(lpemh);
+ }
+ }
+ if (headerValid == TRUE) {
+ UINT size = ::GetEnhMetaFileBits(hemf, 0, NULL);
+ if (size != 0) {
+ LPBYTE lpbits = (LPBYTE)calloc(1, size);
+ if (lpbits != NULL) {
+ if (::GetEnhMetaFileBits(hemf, size, lpbits) == size) {
+ nExitCode = CODE_OK;
+ }
+ free(lpbits);
+ }
+ }
+ }
+ break;
+ }
+ }
+ } else {
+ nExitCode = CODE_INVALID_TYMED_FAILURE;
+ }
+ }
+
+ DumpTestResult(tymed, nExitCode);
+ ::ReleaseStgMedium(&stgmedium);
+ return nExitCode;
+}
+
+void
+TestDropTarget::DumpTestResult(DWORD tymed, int nTestResult) {
+ switch (tymed) {
+ case TYMED_HGLOBAL:
+ fprintf(stderr,"Test transfer for TYMED_HGLOBAL: ");
+ break;
+ case TYMED_ISTREAM:
+ fprintf(stderr,"Test transfer for TYMED_ISTREAM: ");
+ break;
+ case TYMED_ENHMF:
+ fprintf(stderr,"Test transfer for TYMED_ENHMF: ");
+ break;
+ default:
+ fprintf(stderr,"Test transfer for unknown TYMED %d: ", tymed);
+ break;
+ }
+
+ switch (nTestResult) {
+ case CODE_OK:
+ fprintf(stderr,"PASSED");
+ break;
+ case CODE_INVALID_TYMED_FAILURE:
+ fprintf(stderr,"FAILED: invalid TYMED detected");
+ break;
+ case CODE_INVALID_DATA_FAILURE:
+ fprintf(stderr,"FAILED: invalid transfer data detected");
+ break;
+ case CODE_OTHER_FAILURE:
+ fprintf(stderr,"FAILED: other failure detected");
+ break;
+ default:
+ fprintf(stderr,"FAILED: unknown test result %d", nTestResult);
+ break;
+ }
+
+ fprintf(stderr,"\n");
+}
+
+LRESULT CALLBACK
+WndProc(HWND hWnd, UINT iMessage, WPARAM wParam, LPARAM lParam ) {
+ switch (iMessage) {
+ case WM_DESTROY:
+ ::RevokeDragDrop(hWnd);
+ ::OleUninitialize();
+ ::PostQuitMessage(0);
+ break;
+ default:
+ return ::DefWindowProc( hWnd, iMessage, wParam, lParam );
+ }
+ return 0;
+}
+
+int
+main(int argc, char* argv[]) {
+
+ HMODULE hInstance = ::GetModuleHandle(NULL);
+ WNDCLASS wndclass;
+ wndclass.style = CS_OWNDC;
+ wndclass.lpfnWndProc = WndProc;
+ wndclass.cbClsExtra = 0;
+ wndclass.cbWndExtra = 0;
+ wndclass.hInstance = hInstance;
+ wndclass.hIcon = NULL;
+ wndclass.hCursor = NULL;
+ wndclass.hbrBackground = (HBRUSH)::GetStockObject(WHITE_BRUSH);
+ wndclass.lpszMenuName = NULL;
+ wndclass.lpszClassName = szClassName;
+ if (::RegisterClass(&wndclass) == 0) {
+ exit( FALSE );
+ }
+ HWND hMainWnd = ::CreateWindowEx(WS_EX_CLIENTEDGE, szClassName, szClassName,
+ WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN,
+ X, Y, WIDTH, HEIGHT,
+ NULL, NULL, hInstance, NULL);
+ if (hMainWnd == NULL) {
+ exit(FALSE);
+ }
+ ::ShowWindow(hMainWnd, SW_SHOWNORMAL);
+ ::UpdateWindow(hMainWnd);
+ ::OleInitialize(NULL);
+ HRESULT res = ::RegisterDragDrop(hMainWnd, new TestDropTarget());
+ MSG msg;
+
+ while (::GetMessage(&msg, NULL, 0, 0)) {
+ ::TranslateMessage(&msg);
+ ::DispatchMessage(&msg);
+ }
+
+ ::OleUninitialize();
+ ::UnregisterClass(szClassName, hInstance);
+ return msg.wParam;
+}