jdk/src/windows/native/sun/windows/awt_DataTransferer.cpp
author erikj
Thu, 07 Jun 2012 18:05:09 -0700
changeset 12813 c10ab96dcf41
parent 7668 d4a77089c587
child 18232 b538b71fb429
permissions -rw-r--r--
7170969: Add @GenerateNativeHeader to classes whose fields need to be exported for JNI Reviewed-by: ohair, ohrstrom, ihse
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
     1
/*
7668
d4a77089c587 6962318: Update copyright year
ohair
parents: 6489
diff changeset
     2
 * Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved.
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
     3
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
90ce3da70b43 Initial load
duke
parents:
diff changeset
     4
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
     5
 * This code is free software; you can redistribute it and/or modify it
90ce3da70b43 Initial load
duke
parents:
diff changeset
     6
 * under the terms of the GNU General Public License version 2 only, as
5506
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 1976
diff changeset
     7
 * published by the Free Software Foundation.  Oracle designates this
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
     8
 * particular file as subject to the "Classpath" exception as provided
5506
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 1976
diff changeset
     9
 * by Oracle in the LICENSE file that accompanied this code.
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    10
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    11
 * This code is distributed in the hope that it will be useful, but WITHOUT
90ce3da70b43 Initial load
duke
parents:
diff changeset
    12
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
90ce3da70b43 Initial load
duke
parents:
diff changeset
    13
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
90ce3da70b43 Initial load
duke
parents:
diff changeset
    14
 * version 2 for more details (a copy is included in the LICENSE file that
90ce3da70b43 Initial load
duke
parents:
diff changeset
    15
 * accompanied this code).
90ce3da70b43 Initial load
duke
parents:
diff changeset
    16
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    17
 * You should have received a copy of the GNU General Public License version
90ce3da70b43 Initial load
duke
parents:
diff changeset
    18
 * 2 along with this work; if not, write to the Free Software Foundation,
90ce3da70b43 Initial load
duke
parents:
diff changeset
    19
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    20
 *
5506
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 1976
diff changeset
    21
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 1976
diff changeset
    22
 * or visit www.oracle.com if you need additional information or have any
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 1976
diff changeset
    23
 * questions.
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    24
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    25
90ce3da70b43 Initial load
duke
parents:
diff changeset
    26
#include "awt.h"
90ce3da70b43 Initial load
duke
parents:
diff changeset
    27
#include "awt_DataTransferer.h"
90ce3da70b43 Initial load
duke
parents:
diff changeset
    28
#include "awt_DnDDT.h"
90ce3da70b43 Initial load
duke
parents:
diff changeset
    29
#include "awt_TextComponent.h"
90ce3da70b43 Initial load
duke
parents:
diff changeset
    30
#include <shlobj.h>
1954
b93b85df3211 6585765: RFE: Remove Unicows-related code from AWT
art
parents: 2
diff changeset
    31
#include <shellapi.h>
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    32
#include <sun_awt_windows_WDataTransferer.h>
90ce3da70b43 Initial load
duke
parents:
diff changeset
    33
90ce3da70b43 Initial load
duke
parents:
diff changeset
    34
#include "locale_str.h"
90ce3da70b43 Initial load
duke
parents:
diff changeset
    35
90ce3da70b43 Initial load
duke
parents:
diff changeset
    36
#define GALLOCFLG (GMEM_DDESHARE | GMEM_MOVEABLE | GMEM_ZEROINIT)
90ce3da70b43 Initial load
duke
parents:
diff changeset
    37
#define WIN_TO_JAVA_PIXEL(r, g, b) (0xFF000000 | (r) << 16 | (g) << 8  | (b) << 0)
90ce3da70b43 Initial load
duke
parents:
diff changeset
    38
90ce3da70b43 Initial load
duke
parents:
diff changeset
    39
DECLARE_JAVA_CLASS(dataTransfererClazz, "sun/awt/datatransfer/DataTransferer");
90ce3da70b43 Initial load
duke
parents:
diff changeset
    40
90ce3da70b43 Initial load
duke
parents:
diff changeset
    41
jobject
90ce3da70b43 Initial load
duke
parents:
diff changeset
    42
AwtDataTransferer::GetDataTransferer(JNIEnv* env) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    43
    DECLARE_STATIC_OBJECT_JAVA_METHOD(getInstanceMethodID, dataTransfererClazz,
90ce3da70b43 Initial load
duke
parents:
diff changeset
    44
                                      "getInstance",
90ce3da70b43 Initial load
duke
parents:
diff changeset
    45
                                      "()Lsun/awt/datatransfer/DataTransferer;");
90ce3da70b43 Initial load
duke
parents:
diff changeset
    46
    return env->CallStaticObjectMethod(clazz, getInstanceMethodID);
90ce3da70b43 Initial load
duke
parents:
diff changeset
    47
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
    48
90ce3da70b43 Initial load
duke
parents:
diff changeset
    49
jbyteArray
90ce3da70b43 Initial load
duke
parents:
diff changeset
    50
AwtDataTransferer::ConvertData(JNIEnv* env, jobject source, jobject contents,
90ce3da70b43 Initial load
duke
parents:
diff changeset
    51
                               jlong format, jobject formatMap) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    52
    jobject transferer = GetDataTransferer(env);
90ce3da70b43 Initial load
duke
parents:
diff changeset
    53
90ce3da70b43 Initial load
duke
parents:
diff changeset
    54
    if (!JNU_IsNull(env, transferer)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    55
        jbyteArray ret = NULL;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    56
        DECLARE_OBJECT_JAVA_METHOD(convertDataMethodID, dataTransfererClazz,
90ce3da70b43 Initial load
duke
parents:
diff changeset
    57
                                   "convertData",
90ce3da70b43 Initial load
duke
parents:
diff changeset
    58
                                   "(Ljava/lang/Object;Ljava/awt/datatransfer/Transferable;JLjava/util/Map;Z)[B");
90ce3da70b43 Initial load
duke
parents:
diff changeset
    59
90ce3da70b43 Initial load
duke
parents:
diff changeset
    60
        ret = (jbyteArray)env->CallObjectMethod(transferer, convertDataMethodID,
90ce3da70b43 Initial load
duke
parents:
diff changeset
    61
                                                source, contents, format,
90ce3da70b43 Initial load
duke
parents:
diff changeset
    62
                                                formatMap, AwtToolkit::IsMainThread());
90ce3da70b43 Initial load
duke
parents:
diff changeset
    63
90ce3da70b43 Initial load
duke
parents:
diff changeset
    64
        if (!JNU_IsNull(env, safe_ExceptionOccurred(env))) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    65
            env->ExceptionDescribe();
90ce3da70b43 Initial load
duke
parents:
diff changeset
    66
            env->ExceptionClear();
90ce3da70b43 Initial load
duke
parents:
diff changeset
    67
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
    68
90ce3da70b43 Initial load
duke
parents:
diff changeset
    69
        env->DeleteLocalRef(transferer);
90ce3da70b43 Initial load
duke
parents:
diff changeset
    70
90ce3da70b43 Initial load
duke
parents:
diff changeset
    71
        return ret;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    72
    } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    73
        return NULL;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    74
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
    75
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
    76
90ce3da70b43 Initial load
duke
parents:
diff changeset
    77
jobject
90ce3da70b43 Initial load
duke
parents:
diff changeset
    78
AwtDataTransferer::ConcatData(JNIEnv* env, jobject obj1, jobject obj2) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    79
    jobject transferer = GetDataTransferer(env);
90ce3da70b43 Initial load
duke
parents:
diff changeset
    80
90ce3da70b43 Initial load
duke
parents:
diff changeset
    81
    if (!JNU_IsNull(env, transferer)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    82
        jobject ret = NULL;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    83
        DECLARE_OBJECT_JAVA_METHOD(concatDataMethodID, dataTransfererClazz,
90ce3da70b43 Initial load
duke
parents:
diff changeset
    84
                                   "concatData",
90ce3da70b43 Initial load
duke
parents:
diff changeset
    85
                                   "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;");
90ce3da70b43 Initial load
duke
parents:
diff changeset
    86
90ce3da70b43 Initial load
duke
parents:
diff changeset
    87
        ret = env->CallObjectMethod(transferer, concatDataMethodID, obj1, obj2);
90ce3da70b43 Initial load
duke
parents:
diff changeset
    88
90ce3da70b43 Initial load
duke
parents:
diff changeset
    89
        if (!JNU_IsNull(env, safe_ExceptionOccurred(env))) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    90
            env->ExceptionDescribe();
90ce3da70b43 Initial load
duke
parents:
diff changeset
    91
            env->ExceptionClear();
90ce3da70b43 Initial load
duke
parents:
diff changeset
    92
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
    93
90ce3da70b43 Initial load
duke
parents:
diff changeset
    94
        env->DeleteLocalRef(transferer);
90ce3da70b43 Initial load
duke
parents:
diff changeset
    95
90ce3da70b43 Initial load
duke
parents:
diff changeset
    96
        return ret;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    97
    } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    98
        return NULL;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    99
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   100
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   101
90ce3da70b43 Initial load
duke
parents:
diff changeset
   102
/**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   103
 * This routine retrieves palette entries from enhanced metafile or
90ce3da70b43 Initial load
duke
parents:
diff changeset
   104
 * a logical color palette, builds appropriate LOGPALETTE structure,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   105
 * writes it into a created Java byte array and returns a local
90ce3da70b43 Initial load
duke
parents:
diff changeset
   106
 * reference to the array.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   107
 * This routine is used for image data transfer.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   108
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   109
 * @param hGdiObj - a handle to the GDI object to retrieve palette entries from,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   110
 *        it can be a handle to either a logical color palette (OBJ_PAL type)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   111
 *        or an enhanced metafile (OBJ_ENHMETAFILE). If it is neither of these
90ce3da70b43 Initial load
duke
parents:
diff changeset
   112
 *        types the routine fails(see bFailSafe).
90ce3da70b43 Initial load
duke
parents:
diff changeset
   113
 * @param dwGdiObjType - a type of the passed GDI object. It should be specified
90ce3da70b43 Initial load
duke
parents:
diff changeset
   114
 *        if the type of the passed GDI object is known to the caller. Otherwise
90ce3da70b43 Initial load
duke
parents:
diff changeset
   115
 *        pass 0.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   116
 * @param bFailSafe - if FALSE, the routine will return NULL in case of failure,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   117
 *        otherwise it will return an array with empty LOGPALETTE structure
90ce3da70b43 Initial load
duke
parents:
diff changeset
   118
 *        in case of failure.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   119
 * @return a local reference to Java byte array which contains LOGPALETTE
90ce3da70b43 Initial load
duke
parents:
diff changeset
   120
 *        structure which defines a logical color palette or a palette of
90ce3da70b43 Initial load
duke
parents:
diff changeset
   121
 *        an enhanced metafile.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   122
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   123
jbyteArray
90ce3da70b43 Initial load
duke
parents:
diff changeset
   124
AwtDataTransferer::GetPaletteBytes(HGDIOBJ hGdiObj, DWORD dwGdiObjType,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   125
                                   BOOL bFailSafe) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   126
90ce3da70b43 Initial load
duke
parents:
diff changeset
   127
    if (hGdiObj == NULL) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   128
        dwGdiObjType = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   129
    } else if (dwGdiObjType == 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   130
        dwGdiObjType = ::GetObjectType(hGdiObj);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   131
    } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   132
        DASSERT(::GetObjectType(hGdiObj) == dwGdiObjType);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   133
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   134
90ce3da70b43 Initial load
duke
parents:
diff changeset
   135
    if (!bFailSafe && dwGdiObjType == 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   136
        return NULL;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   137
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   138
90ce3da70b43 Initial load
duke
parents:
diff changeset
   139
    UINT nEntries = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   140
90ce3da70b43 Initial load
duke
parents:
diff changeset
   141
    switch (dwGdiObjType) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   142
    case OBJ_PAL:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   143
        nEntries =
90ce3da70b43 Initial load
duke
parents:
diff changeset
   144
            ::GetPaletteEntries((HPALETTE)hGdiObj, 0, 0, NULL);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   145
        break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   146
    case OBJ_ENHMETAFILE:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   147
        nEntries =
90ce3da70b43 Initial load
duke
parents:
diff changeset
   148
            ::GetEnhMetaFilePaletteEntries((HENHMETAFILE)hGdiObj, 0, NULL);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   149
        break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   150
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   151
90ce3da70b43 Initial load
duke
parents:
diff changeset
   152
    if (!bFailSafe && (nEntries == 0 || nEntries == GDI_ERROR)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   153
        return NULL;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   154
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   155
90ce3da70b43 Initial load
duke
parents:
diff changeset
   156
    JNIEnv* env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   157
    jsize size = sizeof(LOGPALETTE) + nEntries * sizeof(PALETTEENTRY);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   158
90ce3da70b43 Initial load
duke
parents:
diff changeset
   159
    jbyteArray paletteBytes = env->NewByteArray(size);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   160
    if (JNU_IsNull(env, paletteBytes)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   161
        throw std::bad_alloc();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   162
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   163
90ce3da70b43 Initial load
duke
parents:
diff changeset
   164
    LOGPALETTE* pLogPalette =
90ce3da70b43 Initial load
duke
parents:
diff changeset
   165
        (LOGPALETTE*)env->GetPrimitiveArrayCritical(paletteBytes, NULL);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   166
    PALETTEENTRY* pPalEntries = (PALETTEENTRY*)pLogPalette->palPalEntry;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   167
90ce3da70b43 Initial load
duke
parents:
diff changeset
   168
    pLogPalette->palVersion = 0x300;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   169
    pLogPalette->palNumEntries = nEntries;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   170
90ce3da70b43 Initial load
duke
parents:
diff changeset
   171
    switch (dwGdiObjType) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   172
    case OBJ_PAL:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   173
        VERIFY(::GetPaletteEntries((HPALETTE)hGdiObj, 0, nEntries,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   174
                                   pPalEntries) == nEntries);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   175
        break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   176
    case OBJ_ENHMETAFILE:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   177
        VERIFY(::GetEnhMetaFilePaletteEntries((HENHMETAFILE)hGdiObj, nEntries,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   178
                                              pPalEntries) == nEntries);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   179
        break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   180
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   181
90ce3da70b43 Initial load
duke
parents:
diff changeset
   182
    env->ReleasePrimitiveArrayCritical(paletteBytes, pLogPalette, 0);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   183
90ce3da70b43 Initial load
duke
parents:
diff changeset
   184
    return paletteBytes;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   185
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   186
90ce3da70b43 Initial load
duke
parents:
diff changeset
   187
jbyteArray
90ce3da70b43 Initial load
duke
parents:
diff changeset
   188
AwtDataTransferer::LCIDToTextEncoding(JNIEnv *env, LCID lcid) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   189
    LANGID langID = LANGIDFROMLCID(lcid);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   190
    const char *encoding = getEncodingFromLangID(langID);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   191
90ce3da70b43 Initial load
duke
parents:
diff changeset
   192
    // Warning C4244.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   193
    // Cast SIZE_T (__int64 on 64-bit/unsigned int on 32-bit)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   194
    // to jsize (long).
90ce3da70b43 Initial load
duke
parents:
diff changeset
   195
    // We assume that the encoding name length cannot exceed INT_MAX.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   196
    jsize length = (jsize)strlen(encoding);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   197
90ce3da70b43 Initial load
duke
parents:
diff changeset
   198
    jbyteArray retval = env->NewByteArray(length);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   199
    if (retval == NULL) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   200
        throw std::bad_alloc();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   201
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   202
    env->SetByteArrayRegion(retval, 0, length, (jbyte *)encoding);
6489
9e7015635425 4700857: RFE: separating user locale and user interface locale
naoto
parents: 5506
diff changeset
   203
    free((void *)encoding);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   204
    return retval;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   205
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   206
90ce3da70b43 Initial load
duke
parents:
diff changeset
   207
static VOID CALLBACK
90ce3da70b43 Initial load
duke
parents:
diff changeset
   208
IdleFunc() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   209
    /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   210
     * Fix for 4485987 and 4669873.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   211
     * If IdleFunc is a noop, the secondary message pump occasionally occupies
90ce3da70b43 Initial load
duke
parents:
diff changeset
   212
     * all processor time and causes drag freezes. GetQueueStatus is needed to
90ce3da70b43 Initial load
duke
parents:
diff changeset
   213
     * mark all messages that are currently in the queue as old, otherwise
90ce3da70b43 Initial load
duke
parents:
diff changeset
   214
     * WaitMessage will return immediatelly as we selectively get messages from
90ce3da70b43 Initial load
duke
parents:
diff changeset
   215
     * the queue.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   216
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   217
    ::WaitMessage();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   218
    ::GetQueueStatus(QS_ALLINPUT);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   219
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   220
90ce3da70b43 Initial load
duke
parents:
diff changeset
   221
static BOOL CALLBACK
90ce3da70b43 Initial load
duke
parents:
diff changeset
   222
PeekMessageFunc(MSG& msg) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   223
    return ::PeekMessage(&msg, NULL, WM_QUIT, WM_QUIT, PM_REMOVE) ||
90ce3da70b43 Initial load
duke
parents:
diff changeset
   224
           ::PeekMessage(&msg, NULL, WM_AWT_INVOKE_METHOD, WM_AWT_INVOKE_METHOD, PM_REMOVE) ||
90ce3da70b43 Initial load
duke
parents:
diff changeset
   225
           ::PeekMessage(&msg, NULL, WM_PAINT, WM_PAINT, PM_REMOVE);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   226
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   227
90ce3da70b43 Initial load
duke
parents:
diff changeset
   228
void
90ce3da70b43 Initial load
duke
parents:
diff changeset
   229
AwtDataTransferer::SecondaryMessageLoop() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   230
    DASSERT(AwtToolkit::MainThread() == ::GetCurrentThreadId());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   231
90ce3da70b43 Initial load
duke
parents:
diff changeset
   232
    AwtToolkit::GetInstance().MessageLoop(IdleFunc,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   233
                                          PeekMessageFunc);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   234
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   235
90ce3da70b43 Initial load
duke
parents:
diff changeset
   236
extern "C" {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   237
90ce3da70b43 Initial load
duke
parents:
diff changeset
   238
/*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   239
 * Class:     sun_awt_datatransfer_DataTransferer
90ce3da70b43 Initial load
duke
parents:
diff changeset
   240
 * Method:    draqQueryFile
90ce3da70b43 Initial load
duke
parents:
diff changeset
   241
 * Signature: ([B)[Ljava/lang/String;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   242
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   243
JNIEXPORT jobjectArray JNICALL
90ce3da70b43 Initial load
duke
parents:
diff changeset
   244
Java_sun_awt_windows_WDataTransferer_dragQueryFile
90ce3da70b43 Initial load
duke
parents:
diff changeset
   245
    (JNIEnv *env, jobject obj, jbyteArray bytes)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   246
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
   247
    TRY;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   248
90ce3da70b43 Initial load
duke
parents:
diff changeset
   249
    /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   250
     * Fix for the BugTraq ID 4327064 - inter-jvm DnD crashes the droping jvm.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   251
     * On Win9X DragQueryFile() doesn't accept a pointer to the local help as the first
90ce3da70b43 Initial load
duke
parents:
diff changeset
   252
     * argument, so we should dump the bits into global memory.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   253
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   254
    UINT size = env->GetArrayLength(bytes);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   255
    HGLOBAL hglobal = NULL;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   256
    jbyte *bBytes = NULL;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   257
    HDROP hdrop = NULL;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   258
    LPTSTR buffer = NULL;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   259
90ce3da70b43 Initial load
duke
parents:
diff changeset
   260
    hglobal = ::GlobalAlloc(GALLOCFLG, size);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   261
90ce3da70b43 Initial load
duke
parents:
diff changeset
   262
    if (hglobal == NULL) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   263
        throw std::bad_alloc();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   264
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   265
90ce3da70b43 Initial load
duke
parents:
diff changeset
   266
    try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   267
90ce3da70b43 Initial load
duke
parents:
diff changeset
   268
        bBytes = (jbyte*)::GlobalLock(hglobal);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   269
        env->GetByteArrayRegion(bytes, 0, size, bBytes);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   270
90ce3da70b43 Initial load
duke
parents:
diff changeset
   271
        hdrop = (HDROP)bBytes;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   272
1954
b93b85df3211 6585765: RFE: Remove Unicows-related code from AWT
art
parents: 2
diff changeset
   273
        UINT nFilenames = ::DragQueryFile(hdrop, 0xFFFFFFFF, NULL, 0);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   274
90ce3da70b43 Initial load
duke
parents:
diff changeset
   275
        jclass str_clazz = env->FindClass("java/lang/String");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   276
        DASSERT(str_clazz != NULL);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   277
        jobjectArray filenames = env->NewObjectArray(nFilenames, str_clazz,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   278
                                                     NULL);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   279
        if (filenames == NULL) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   280
            throw std::bad_alloc();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   281
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   282
90ce3da70b43 Initial load
duke
parents:
diff changeset
   283
        UINT bufsize = 512; // in characters, not in bytes
90ce3da70b43 Initial load
duke
parents:
diff changeset
   284
        buffer = (LPTSTR)safe_Malloc(bufsize*sizeof(TCHAR));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   285
90ce3da70b43 Initial load
duke
parents:
diff changeset
   286
        for (UINT i = 0; i < nFilenames; i++) {
1954
b93b85df3211 6585765: RFE: Remove Unicows-related code from AWT
art
parents: 2
diff changeset
   287
            UINT size = ::DragQueryFile(hdrop, i, NULL, 0);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   288
            if (size > bufsize) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   289
                bufsize = size;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   290
                buffer = (LPTSTR)safe_Realloc(buffer, bufsize*sizeof(TCHAR));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   291
            }
1954
b93b85df3211 6585765: RFE: Remove Unicows-related code from AWT
art
parents: 2
diff changeset
   292
            ::DragQueryFile(hdrop, i, buffer, bufsize);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   293
90ce3da70b43 Initial load
duke
parents:
diff changeset
   294
            jstring name = JNU_NewStringPlatform(env, buffer);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   295
            if (name == NULL) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   296
                throw std::bad_alloc();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   297
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   298
90ce3da70b43 Initial load
duke
parents:
diff changeset
   299
            env->SetObjectArrayElement(filenames, i, name);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   300
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   301
90ce3da70b43 Initial load
duke
parents:
diff changeset
   302
        free(buffer);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   303
        ::GlobalUnlock(hglobal);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   304
        ::GlobalFree(hglobal);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   305
        return filenames;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   306
90ce3da70b43 Initial load
duke
parents:
diff changeset
   307
    } catch (std::bad_alloc&) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   308
        free(buffer);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   309
        ::GlobalUnlock(hglobal);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   310
        ::GlobalFree(hglobal);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   311
        throw;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   312
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   313
90ce3da70b43 Initial load
duke
parents:
diff changeset
   314
    CATCH_BAD_ALLOC_RET(NULL);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   315
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   316
90ce3da70b43 Initial load
duke
parents:
diff changeset
   317
/*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   318
 * Class:     sun_awt_windows_WDataTransferer
90ce3da70b43 Initial load
duke
parents:
diff changeset
   319
 * Method:    platformImageBytesToImageData
90ce3da70b43 Initial load
duke
parents:
diff changeset
   320
 * Signature: ([BI)[I
90ce3da70b43 Initial load
duke
parents:
diff changeset
   321
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   322
JNIEXPORT jintArray JNICALL
90ce3da70b43 Initial load
duke
parents:
diff changeset
   323
Java_sun_awt_windows_WDataTransferer_platformImageBytesToImageData(
90ce3da70b43 Initial load
duke
parents:
diff changeset
   324
    JNIEnv *env, jobject self, jbyteArray bytes, jlong format) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   325
90ce3da70b43 Initial load
duke
parents:
diff changeset
   326
    TRY;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   327
90ce3da70b43 Initial load
duke
parents:
diff changeset
   328
    HDC hdc = NULL;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   329
90ce3da70b43 Initial load
duke
parents:
diff changeset
   330
    LOGPALETTE* pLogPalette = NULL;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   331
    WORD uPaletteEntries = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   332
    SIZE_T uOffset = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   333
    HPALETTE hPalette = NULL;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   334
    HPALETTE hOldPalette = NULL;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   335
90ce3da70b43 Initial load
duke
parents:
diff changeset
   336
    BITMAPINFO* pSrcBmi = NULL;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   337
    BITMAPINFOHEADER* pSrcBmih = NULL;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   338
    LPVOID pSrcBits = NULL;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   339
    BITMAPINFO* pDstBmi = NULL;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   340
    BITMAPINFOHEADER* pDstBmih = NULL;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   341
    LPVOID pDstBits = NULL;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   342
90ce3da70b43 Initial load
duke
parents:
diff changeset
   343
    LPBYTE lpEnhMetaFileBits = NULL;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   344
    HENHMETAFILE hEnhMetaFile = NULL;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   345
90ce3da70b43 Initial load
duke
parents:
diff changeset
   346
    HBITMAP hDibSection = NULL;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   347
    HBITMAP hOldBitmap = NULL;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   348
    jintArray buffer = NULL;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   349
    LONG width = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   350
    LONG height = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   351
    int numPixels = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   352
90ce3da70b43 Initial load
duke
parents:
diff changeset
   353
    if (JNU_IsNull(env, bytes)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   354
        return NULL;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   355
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   356
90ce3da70b43 Initial load
duke
parents:
diff changeset
   357
    jsize size = env->GetArrayLength(bytes);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   358
    if (size == 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   359
        return NULL;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   360
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   361
90ce3da70b43 Initial load
duke
parents:
diff changeset
   362
    jbyte* bBytes = (jbyte*)safe_Malloc(size * sizeof(jbyte));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   363
90ce3da70b43 Initial load
duke
parents:
diff changeset
   364
    try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   365
90ce3da70b43 Initial load
duke
parents:
diff changeset
   366
        env->GetByteArrayRegion(bytes, 0, size, bBytes);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   367
90ce3da70b43 Initial load
duke
parents:
diff changeset
   368
        pLogPalette = (LOGPALETTE*)bBytes;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   369
        uPaletteEntries = pLogPalette->palNumEntries;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   370
        uOffset = sizeof(LOGPALETTE) + uPaletteEntries * sizeof(PALETTEENTRY);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   371
        DASSERT(uOffset < (SIZE_T)size);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   372
90ce3da70b43 Initial load
duke
parents:
diff changeset
   373
        if (uPaletteEntries == 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   374
            pLogPalette = NULL;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   375
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   376
90ce3da70b43 Initial load
duke
parents:
diff changeset
   377
        hdc = ::CreateCompatibleDC(NULL);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   378
        if (hdc == NULL) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   379
            free(bBytes);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   380
            return NULL;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   381
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   382
90ce3da70b43 Initial load
duke
parents:
diff changeset
   383
        switch (format) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   384
        case CF_DIB:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   385
90ce3da70b43 Initial load
duke
parents:
diff changeset
   386
            pSrcBmi = (BITMAPINFO*)((LPSTR)bBytes + uOffset);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   387
            pSrcBmih = &pSrcBmi->bmiHeader;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   388
90ce3da70b43 Initial load
duke
parents:
diff changeset
   389
            width = pSrcBmih->biWidth;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   390
            height = abs(pSrcBmih->biHeight);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   391
90ce3da70b43 Initial load
duke
parents:
diff changeset
   392
            {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   393
                DWORD nColorEntries = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   394
90ce3da70b43 Initial load
duke
parents:
diff changeset
   395
                switch (pSrcBmih->biBitCount) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   396
                case  0: nColorEntries = 0; break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   397
                case  1: nColorEntries = 2; break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   398
                case  4:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   399
                case  8:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   400
                    nColorEntries = (pSrcBmih->biClrUsed != 0) ?
1976
91e064d8ddb9 6551075: screenshot image taken through clipboard on W2K terminal server is shifted
bae
parents: 1954
diff changeset
   401
                        pSrcBmih->biClrUsed : (1 << pSrcBmih->biBitCount);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   402
                    break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   403
                case 16:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   404
                case 24:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   405
                case 32:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   406
                    nColorEntries = pSrcBmih->biClrUsed;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   407
                    // If biBitCount is 16 or 32 and biCompression is
90ce3da70b43 Initial load
duke
parents:
diff changeset
   408
                    // BI_BITFIELDS the color table will be prefixed with
90ce3da70b43 Initial load
duke
parents:
diff changeset
   409
                    // three DWORD color masks.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   410
                    if (pSrcBmih->biCompression == BI_BITFIELDS &&
90ce3da70b43 Initial load
duke
parents:
diff changeset
   411
                        (pSrcBmih->biBitCount == 16 ||
90ce3da70b43 Initial load
duke
parents:
diff changeset
   412
                         pSrcBmih->biBitCount == 32)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   413
                        nColorEntries += 3;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   414
                    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   415
                    break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   416
                default:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   417
                    // The header is probably corrupted.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   418
                    // Fail immediatelly to avoid memory access violation.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   419
                    free(bBytes);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   420
                    ::DeleteDC(hdc);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   421
                    return NULL;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   422
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   423
90ce3da70b43 Initial load
duke
parents:
diff changeset
   424
                pSrcBits = (LPSTR)pSrcBmi + pSrcBmih->biSize
90ce3da70b43 Initial load
duke
parents:
diff changeset
   425
                    + nColorEntries * sizeof(RGBQUAD);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   426
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   427
            break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   428
        case CF_ENHMETAFILE:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   429
        case CF_METAFILEPICT:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   430
            lpEnhMetaFileBits = (BYTE*)bBytes + uOffset;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   431
            // Warning C4244. size is jsize, uOffset is SIZE_T.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   432
            // We assert that size > uOffset, so it is safe to cast to jsize.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   433
            hEnhMetaFile = ::SetEnhMetaFileBits(size - (jsize)uOffset,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   434
                                                lpEnhMetaFileBits);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   435
            DASSERT(hEnhMetaFile != NULL);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   436
90ce3da70b43 Initial load
duke
parents:
diff changeset
   437
            {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   438
                UINT uHeaderSize =
90ce3da70b43 Initial load
duke
parents:
diff changeset
   439
                    ::GetEnhMetaFileHeader(hEnhMetaFile, 0, NULL);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   440
                DASSERT(uHeaderSize != 0);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   441
                ENHMETAHEADER* lpemh = (ENHMETAHEADER*)safe_Malloc(uHeaderSize);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   442
                VERIFY(::GetEnhMetaFileHeader(hEnhMetaFile, uHeaderSize,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   443
                                              lpemh) == uHeaderSize);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   444
                LPRECTL lpFrame = &lpemh->rclFrame;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   445
                POINT p = { abs(lpFrame->right - lpFrame->left),
90ce3da70b43 Initial load
duke
parents:
diff changeset
   446
                            abs(lpFrame->bottom - lpFrame->top) };
90ce3da70b43 Initial load
duke
parents:
diff changeset
   447
                VERIFY(::SaveDC(hdc));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   448
                VERIFY(::SetMapMode(hdc, MM_HIMETRIC));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   449
                VERIFY(::LPtoDP(hdc, &p, 1));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   450
                VERIFY(::RestoreDC(hdc, -1));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   451
                width = p.x;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   452
                height = -p.y;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   453
90ce3da70b43 Initial load
duke
parents:
diff changeset
   454
                free(lpemh);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   455
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   456
            break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   457
        default:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   458
            DASSERT(FALSE); // Other formats are not supported yet.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   459
            free(bBytes);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   460
            ::DeleteDC(hdc);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   461
            return NULL;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   462
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   463
90ce3da70b43 Initial load
duke
parents:
diff changeset
   464
        // JNI doesn't allow to store more than INT_MAX in a single array.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   465
        // We report conversion failure in this case.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   466
        if (width * height > INT_MAX) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   467
            free(bBytes);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   468
            ::DeleteDC(hdc);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   469
            return NULL;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   470
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   471
90ce3da70b43 Initial load
duke
parents:
diff changeset
   472
        numPixels = width * height;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   473
90ce3da70b43 Initial load
duke
parents:
diff changeset
   474
        if (pLogPalette != NULL) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   475
            hPalette = ::CreatePalette(pLogPalette);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   476
            if (hPalette == NULL) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   477
                free(bBytes);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   478
                ::DeleteDC(hdc);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   479
                return NULL;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   480
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   481
            hOldPalette = ::SelectPalette(hdc, hPalette, FALSE);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   482
            ::RealizePalette(hdc);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   483
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   484
90ce3da70b43 Initial load
duke
parents:
diff changeset
   485
        // allocate memory for BITMAPINFO
90ce3da70b43 Initial load
duke
parents:
diff changeset
   486
        pDstBmi = (BITMAPINFO *)safe_Calloc(1, sizeof(BITMAPINFO));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   487
        pDstBmih = &pDstBmi->bmiHeader;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   488
90ce3da70b43 Initial load
duke
parents:
diff changeset
   489
        static const int BITS_PER_PIXEL = 32;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   490
90ce3da70b43 Initial load
duke
parents:
diff changeset
   491
        // prepare BITMAPINFO for a 32-bit RGB bitmap
90ce3da70b43 Initial load
duke
parents:
diff changeset
   492
        pDstBmih->biSize = sizeof(BITMAPINFOHEADER);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   493
        pDstBmih->biWidth = width;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   494
        pDstBmih->biHeight = -height; // negative height means a top-down DIB
90ce3da70b43 Initial load
duke
parents:
diff changeset
   495
        pDstBmih->biPlanes = 1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   496
        pDstBmih->biBitCount = BITS_PER_PIXEL;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   497
        pDstBmih->biCompression = BI_RGB;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   498
        // NOTE: MSDN says that biSizeImage may be set to 0 for BI_RGB bitmaps,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   499
        // but this causes CreateDIBSection to allocate zero-size memory block
90ce3da70b43 Initial load
duke
parents:
diff changeset
   500
        // for DIB data. It works okay when biSizeImage is explicitly specified.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   501
        pDstBmih->biSizeImage = width * height * (BITS_PER_PIXEL >> 3);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   502
90ce3da70b43 Initial load
duke
parents:
diff changeset
   503
        hDibSection = ::CreateDIBSection(hdc, (BITMAPINFO*)pDstBmi,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   504
                                         DIB_RGB_COLORS, &pDstBits,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   505
                                         NULL, 0);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   506
90ce3da70b43 Initial load
duke
parents:
diff changeset
   507
        if (hDibSection == NULL) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   508
            free(pDstBmi); pDstBmi = NULL;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   509
            if (hPalette != NULL) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   510
                VERIFY(::SelectPalette(hdc, hOldPalette, FALSE) != NULL);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   511
                hOldPalette = NULL;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   512
                VERIFY(::DeleteObject(hPalette)); hPalette = NULL;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   513
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   514
            VERIFY(::DeleteDC(hdc)); hdc = NULL;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   515
            free(bBytes); bBytes = NULL;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   516
90ce3da70b43 Initial load
duke
parents:
diff changeset
   517
            JNU_ThrowIOException(env, "failed to get drop data");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   518
            return NULL;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   519
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   520
90ce3da70b43 Initial load
duke
parents:
diff changeset
   521
        hOldBitmap = (HBITMAP)::SelectObject(hdc, hDibSection);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   522
        DASSERT(hOldBitmap != NULL);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   523
90ce3da70b43 Initial load
duke
parents:
diff changeset
   524
        switch (format) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   525
        case CF_DIB:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   526
            VERIFY(::StretchDIBits(hdc,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   527
                                   0, 0, width, height,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   528
                                   0, 0, width, height,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   529
                                   pSrcBits, pSrcBmi,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   530
                                   DIB_RGB_COLORS, SRCCOPY) != GDI_ERROR);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   531
            break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   532
        case CF_ENHMETAFILE:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   533
        case CF_METAFILEPICT: {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   534
            RECT rect = { 0, 0, width, height };
90ce3da70b43 Initial load
duke
parents:
diff changeset
   535
90ce3da70b43 Initial load
duke
parents:
diff changeset
   536
            VERIFY(::PlayEnhMetaFile(hdc, hEnhMetaFile, &rect));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   537
            VERIFY(::DeleteEnhMetaFile(hEnhMetaFile)); hEnhMetaFile = NULL;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   538
            break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   539
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   540
        default:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   541
            // Other formats are not supported yet.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   542
            DASSERT(FALSE);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   543
            break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   544
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   545
90ce3da70b43 Initial load
duke
parents:
diff changeset
   546
        // convert Win32 pixel format (BGRX) to Java format (ARGB)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   547
        DASSERT(sizeof(jint) == sizeof(RGBQUAD));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   548
        RGBQUAD* prgbq = (RGBQUAD*)pDstBits;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   549
        for(int nPixel = 0; nPixel < numPixels; nPixel++, prgbq++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   550
            jint jpixel = WIN_TO_JAVA_PIXEL(prgbq->rgbRed,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   551
                                            prgbq->rgbGreen,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   552
                                            prgbq->rgbBlue);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   553
            // stuff the 32-bit pixel back into the 32-bit RGBQUAD
90ce3da70b43 Initial load
duke
parents:
diff changeset
   554
            *prgbq = *((RGBQUAD*)(&jpixel));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   555
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   556
90ce3da70b43 Initial load
duke
parents:
diff changeset
   557
        buffer = env->NewIntArray(numPixels + 2);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   558
        if (buffer == NULL) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   559
            throw std::bad_alloc();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   560
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   561
90ce3da70b43 Initial load
duke
parents:
diff changeset
   562
        // copy pixels into Java array
90ce3da70b43 Initial load
duke
parents:
diff changeset
   563
        env->SetIntArrayRegion(buffer, 0, numPixels, (jint*)pDstBits);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   564
90ce3da70b43 Initial load
duke
parents:
diff changeset
   565
        // copy dimensions into Java array
90ce3da70b43 Initial load
duke
parents:
diff changeset
   566
        env->SetIntArrayRegion(buffer, numPixels, 1, (jint*)&width);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   567
        env->SetIntArrayRegion(buffer, numPixels + 1, 1, (jint*)&height);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   568
90ce3da70b43 Initial load
duke
parents:
diff changeset
   569
        VERIFY(::SelectObject(hdc, hOldBitmap) != NULL); hOldBitmap = NULL;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   570
        VERIFY(::DeleteObject(hDibSection)); hDibSection = NULL;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   571
        free(pDstBmi); pDstBmi = NULL;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   572
        if (hPalette != NULL) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   573
            VERIFY(::SelectPalette(hdc, hOldPalette, FALSE) != NULL);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   574
            hOldPalette = NULL;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   575
            VERIFY(::DeleteObject(hPalette)); hPalette = NULL;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   576
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   577
        VERIFY(::DeleteDC(hdc)); hdc = NULL;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   578
        free(bBytes); bBytes = NULL;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   579
    } catch (...) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   580
        if (hdc != NULL && hOldBitmap != NULL) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   581
            VERIFY(::SelectObject(hdc, hOldBitmap) != NULL); hOldBitmap = NULL;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   582
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   583
        if (hDibSection != NULL) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   584
            VERIFY(::DeleteObject(hDibSection)); hDibSection = NULL;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   585
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   586
        if (pDstBmi != NULL) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   587
            free(pDstBmi); pDstBmi = NULL;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   588
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   589
        if (hPalette != NULL) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   590
            if (hdc != NULL) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   591
                VERIFY(::SelectPalette(hdc, hOldPalette, FALSE) != NULL);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   592
                hOldPalette = NULL;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   593
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   594
            VERIFY(::DeleteObject(hPalette)); hPalette = NULL;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   595
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   596
        if (hdc != NULL) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   597
            VERIFY(::DeleteDC(hdc)); hdc = NULL;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   598
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   599
        if (hEnhMetaFile != NULL) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   600
            VERIFY(::DeleteEnhMetaFile(hEnhMetaFile)); hEnhMetaFile = NULL;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   601
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   602
        if (bBytes != NULL) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   603
            free(bBytes); bBytes = NULL;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   604
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   605
        throw;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   606
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   607
90ce3da70b43 Initial load
duke
parents:
diff changeset
   608
    return buffer;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   609
90ce3da70b43 Initial load
duke
parents:
diff changeset
   610
    CATCH_BAD_ALLOC_RET(NULL);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   611
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   612
90ce3da70b43 Initial load
duke
parents:
diff changeset
   613
/*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   614
 * Class:     sun_awt_windows_WDataTransferer
90ce3da70b43 Initial load
duke
parents:
diff changeset
   615
 * Method:    imageDataToPlatformImageBytes
90ce3da70b43 Initial load
duke
parents:
diff changeset
   616
 * Signature: ([BIII)[B
90ce3da70b43 Initial load
duke
parents:
diff changeset
   617
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   618
JNIEXPORT jbyteArray JNICALL
90ce3da70b43 Initial load
duke
parents:
diff changeset
   619
Java_sun_awt_windows_WDataTransferer_imageDataToPlatformImageBytes(JNIEnv *env,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   620
                                               jobject self, jbyteArray imageData,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   621
                                               jint width, jint height,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   622
                                               jlong format) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   623
90ce3da70b43 Initial load
duke
parents:
diff changeset
   624
    TRY;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   625
90ce3da70b43 Initial load
duke
parents:
diff changeset
   626
    if (JNU_IsNull(env, imageData)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   627
        return NULL;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   628
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   629
90ce3da70b43 Initial load
duke
parents:
diff changeset
   630
    UINT size = env->GetArrayLength(imageData);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   631
    if (size == 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   632
        return NULL;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   633
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   634
90ce3da70b43 Initial load
duke
parents:
diff changeset
   635
    // In the passed imageData array all lines are padded with zeroes except for
90ce3da70b43 Initial load
duke
parents:
diff changeset
   636
    // the last one, so we have to add one pad size here.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   637
    int mod = (width * 3) % 4;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   638
    int pad = mod > 0 ? 4 - mod : 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   639
    int nBytes = sizeof(BITMAPINFO) + size + pad;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   640
    BITMAPINFO* pinfo = (BITMAPINFO*)safe_Calloc(1, nBytes);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   641
90ce3da70b43 Initial load
duke
parents:
diff changeset
   642
    static const int BITS_PER_PIXEL = 24;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   643
90ce3da70b43 Initial load
duke
parents:
diff changeset
   644
    // prepare BITMAPINFO for a 24-bit BGR bitmap
90ce3da70b43 Initial load
duke
parents:
diff changeset
   645
    pinfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   646
    pinfo->bmiHeader.biWidth = width;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   647
    pinfo->bmiHeader.biHeight = height; // positive height means a bottom-up DIB
90ce3da70b43 Initial load
duke
parents:
diff changeset
   648
    pinfo->bmiHeader.biPlanes = 1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   649
    pinfo->bmiHeader.biBitCount = BITS_PER_PIXEL;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   650
    pinfo->bmiHeader.biCompression = BI_RGB;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   651
    // NOTE: MSDN says that biSizeImage may be set to 0 for BI_RGB bitmaps,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   652
    // but some programs (e.g. Imaging for Windows NT by Wang Laboratories)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   653
    // don't handle such DIBs correctly, so we specify the size explicitly.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   654
    pinfo->bmiHeader.biSizeImage = size + pad;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   655
90ce3da70b43 Initial load
duke
parents:
diff changeset
   656
    jbyte *array = (jbyte*)((LPSTR)pinfo + sizeof(BITMAPINFOHEADER));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   657
    env->GetByteArrayRegion(imageData, 0, size, array);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   658
    HRESULT hr = S_OK;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   659
90ce3da70b43 Initial load
duke
parents:
diff changeset
   660
    jbyteArray bytes = NULL;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   661
    switch (format) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   662
    case CF_DIB:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   663
        bytes = env->NewByteArray(nBytes);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   664
        if( NULL == bytes ) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   665
            hr = E_OUTOFMEMORY;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   666
        } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   667
            env->SetByteArrayRegion(bytes, 0, nBytes, (jbyte*)pinfo);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   668
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   669
        break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   670
    case CF_ENHMETAFILE:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   671
    {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   672
        HDC hdc = ::GetDC(NULL);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   673
        if( NULL == hdc) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   674
            hr = HRESULT_FROM_WIN32(::GetLastError());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   675
        } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   676
            POINT p = { width, height };
90ce3da70b43 Initial load
duke
parents:
diff changeset
   677
            //We are trying to support context-independent metafile.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   678
            //To implement it we have to select correct MM_HIMETRIC map mode.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   679
            VERIFY(::SetMapMode(hdc, MM_HIMETRIC));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   680
            VERIFY(::DPtoLP(hdc, &p, 1));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   681
            //In accordance with CreateEnhMetaFile documentation the rectangle have to
90ce3da70b43 Initial load
duke
parents:
diff changeset
   682
            //be normal (left <= right, top <= bottom)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   683
            RECT r = { min(0, p.x), min(0, p.y), max(0, p.x), max(0, p.y) };
90ce3da70b43 Initial load
duke
parents:
diff changeset
   684
            //Due to inversed row order in source bitmap the destination
90ce3da70b43 Initial load
duke
parents:
diff changeset
   685
            //height have to be negative.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   686
            HDC hemfdc = ::CreateEnhMetaFile(NULL, NULL, &r, NULL);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   687
            if( NULL == hemfdc) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   688
                hr = HRESULT_FROM_WIN32(::GetLastError());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   689
            } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   690
                int iMFHeight = r.bottom - r.top;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   691
                int iMFWidth = r.right - r.left;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   692
                VERIFY(::SetMapMode(hemfdc, MM_HIMETRIC));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   693
                if( GDI_ERROR == ::StretchDIBits(hemfdc,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   694
                    0, iMFHeight, iMFWidth, -iMFHeight,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   695
                    0, 0, width, height,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   696
                    (LPVOID)array, pinfo,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   697
                    DIB_RGB_COLORS, SRCCOPY))
90ce3da70b43 Initial load
duke
parents:
diff changeset
   698
                {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   699
                    hr = HRESULT_FROM_WIN32(::GetLastError());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   700
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   701
                HENHMETAFILE hemf = ::CloseEnhMetaFile(hemfdc);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   702
                if( NULL == hemf) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   703
                    hr = HRESULT_FROM_WIN32(::GetLastError());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   704
                } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   705
                    if(SUCCEEDED(hr)){
90ce3da70b43 Initial load
duke
parents:
diff changeset
   706
                        UINT uEmfSize = ::GetEnhMetaFileBits(hemf, 0, NULL);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   707
                        if( 0 == uEmfSize) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   708
                            hr = HRESULT_FROM_WIN32(::GetLastError());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   709
                        } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   710
                            LPBYTE lpbEmfBuffer = NULL;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   711
                            try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   712
                                lpbEmfBuffer = (LPBYTE)safe_Malloc(uEmfSize);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   713
                                VERIFY(::GetEnhMetaFileBits(hemf, uEmfSize,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   714
                                                            lpbEmfBuffer) == uEmfSize);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   715
                                bytes = env->NewByteArray(uEmfSize);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   716
                                if(NULL == bytes) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   717
                                    hr = E_OUTOFMEMORY;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   718
                                } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   719
                                    env->SetByteArrayRegion(bytes, 0, uEmfSize, (jbyte*)lpbEmfBuffer);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   720
                                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   721
                            } catch (std::bad_alloc &) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   722
                                hr = E_OUTOFMEMORY;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   723
                            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   724
                            free(lpbEmfBuffer);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   725
                        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   726
                    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   727
                    VERIFY(::DeleteEnhMetaFile(hemf));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   728
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   729
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   730
            VERIFY(::ReleaseDC(NULL, hdc));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   731
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   732
        break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   733
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   734
    case CF_METAFILEPICT:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   735
    {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   736
        HDC hdc = ::GetDC(NULL);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   737
        if( NULL == hdc) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   738
            hr = HRESULT_FROM_WIN32(::GetLastError());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   739
        } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   740
            POINT p = { width, height };
90ce3da70b43 Initial load
duke
parents:
diff changeset
   741
            VERIFY(::SetMapMode(hdc, MM_HIMETRIC));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   742
            VERIFY(::DPtoLP(hdc, &p, 1));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   743
            RECT r = { min(0, p.x), min(0, p.y), max(0, p.x), max(0, p.y) };
90ce3da70b43 Initial load
duke
parents:
diff changeset
   744
            HDC hmfdc = ::CreateMetaFile(NULL);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   745
            if( NULL == hmfdc) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   746
                hr = HRESULT_FROM_WIN32(::GetLastError());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   747
            } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   748
                VERIFY(::SetMapMode(hmfdc, MM_HIMETRIC));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   749
                int iMFHeight = r.bottom - r.top;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   750
                int iMFWidth = r.right - r.left;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   751
                //The destination Y coordinate (3d parameter in StretchDIBits call) is different for
90ce3da70b43 Initial load
duke
parents:
diff changeset
   752
                //CF_ENHMETAFILE and CF_METAFILEPICT formats due to applying MM_ANISOTROPIC map mode
90ce3da70b43 Initial load
duke
parents:
diff changeset
   753
                //at very last moment. MM_ANISOTROPIC map mode changes the Y-axis direction and can be
90ce3da70b43 Initial load
duke
parents:
diff changeset
   754
                //selected just for metafile header.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   755
                if( GDI_ERROR == ::StretchDIBits(hmfdc,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   756
                    0, 0, iMFWidth, -iMFHeight,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   757
                    0, 0, width, height,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   758
                    (LPVOID)array, pinfo,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   759
                    DIB_RGB_COLORS, SRCCOPY))
90ce3da70b43 Initial load
duke
parents:
diff changeset
   760
                {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   761
                    hr = HRESULT_FROM_WIN32(::GetLastError());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   762
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   763
                HMETAFILE hmf = ::CloseMetaFile(hmfdc);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   764
                if( NULL == hmf) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   765
                    hr = HRESULT_FROM_WIN32(::GetLastError());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   766
                } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   767
                    if(SUCCEEDED(hr)){
90ce3da70b43 Initial load
duke
parents:
diff changeset
   768
                        UINT uMfSize = ::GetMetaFileBitsEx(hmf, 0, NULL);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   769
                        if( 0 == uMfSize) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   770
                            hr = HRESULT_FROM_WIN32(::GetLastError());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   771
                        } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   772
                            LPBYTE lpbMfBuffer = NULL;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   773
                            try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   774
                                UINT uMfSizeWithHead = uMfSize + sizeof(METAFILEPICT);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   775
90ce3da70b43 Initial load
duke
parents:
diff changeset
   776
                                lpbMfBuffer = (LPBYTE)safe_Malloc(uMfSizeWithHead);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   777
                                VERIFY(::GetMetaFileBitsEx(hmf, uMfSize,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   778
                                                            lpbMfBuffer + sizeof(METAFILEPICT)) == uMfSize);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   779
                                bytes = env->NewByteArray(uMfSizeWithHead);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   780
                                if(NULL == bytes) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   781
                                    hr = E_OUTOFMEMORY;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   782
                                } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   783
                                    LPMETAFILEPICT lpMfp = (LPMETAFILEPICT)lpbMfBuffer;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   784
                                    lpMfp->mm = MM_ANISOTROPIC; // should use MM_ANISOTROPIC exactly (MSDN)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   785
                                    lpMfp->xExt = iMFWidth;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   786
                                    lpMfp->yExt = iMFHeight;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   787
                                    env->SetByteArrayRegion(bytes, 0, uMfSizeWithHead, (jbyte*)lpbMfBuffer);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   788
                                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   789
                            } catch (std::bad_alloc &) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   790
                                hr = E_OUTOFMEMORY;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   791
                            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   792
                            free(lpbMfBuffer);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   793
                        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   794
                    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   795
                    VERIFY(::DeleteMetaFile(hmf));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   796
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   797
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   798
            VERIFY(::ReleaseDC(NULL, hdc));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   799
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   800
        break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   801
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   802
    default:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   803
        DASSERT(FALSE); // Other formats are not supported yet.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   804
        hr = E_NOTIMPL;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   805
        break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   806
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   807
    free(pinfo);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   808
    if(FAILED(hr)){
90ce3da70b43 Initial load
duke
parents:
diff changeset
   809
        if(E_OUTOFMEMORY == hr)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   810
            throw std::bad_alloc();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   811
        return NULL;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   812
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   813
    return bytes;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   814
    CATCH_BAD_ALLOC_RET(NULL);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   815
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   816
90ce3da70b43 Initial load
duke
parents:
diff changeset
   817
/*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   818
 * Class:     sun_awt_windows_WDataTransferer
90ce3da70b43 Initial load
duke
parents:
diff changeset
   819
 * Method:    registerClipboardFormat
90ce3da70b43 Initial load
duke
parents:
diff changeset
   820
 * Signature: (Ljava/lang/String;)J
90ce3da70b43 Initial load
duke
parents:
diff changeset
   821
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   822
JNIEXPORT jlong JNICALL
90ce3da70b43 Initial load
duke
parents:
diff changeset
   823
Java_sun_awt_windows_WDataTransferer_registerClipboardFormat(JNIEnv *env,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   824
                                                             jclass cls,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   825
                                                             jstring str)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   826
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
   827
    TRY;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   828
90ce3da70b43 Initial load
duke
parents:
diff changeset
   829
    LPCTSTR cStr = JNU_GetStringPlatformChars(env, str, NULL);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   830
    jlong value = ::RegisterClipboardFormat(cStr);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   831
    JNU_ReleaseStringPlatformChars(env, str, cStr);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   832
90ce3da70b43 Initial load
duke
parents:
diff changeset
   833
    return value;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   834
90ce3da70b43 Initial load
duke
parents:
diff changeset
   835
    CATCH_BAD_ALLOC_RET(0);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   836
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   837
90ce3da70b43 Initial load
duke
parents:
diff changeset
   838
/*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   839
 * Class:     sun_awt_windows_WDataTransferer
90ce3da70b43 Initial load
duke
parents:
diff changeset
   840
 * Method:    getClipboardFormatName
90ce3da70b43 Initial load
duke
parents:
diff changeset
   841
 * Signature: (J)Ljava/lang/String;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   842
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   843
JNIEXPORT jstring JNICALL
90ce3da70b43 Initial load
duke
parents:
diff changeset
   844
Java_sun_awt_windows_WDataTransferer_getClipboardFormatName(JNIEnv *env,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   845
                                                            jclass cls,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   846
                                                            jlong format)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   847
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
   848
    TRY;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   849
90ce3da70b43 Initial load
duke
parents:
diff changeset
   850
    LPTSTR buf = new TCHAR[512]; // perhaps a bad idea to limit ourselves to 512
90ce3da70b43 Initial load
duke
parents:
diff changeset
   851
    VERIFY(::GetClipboardFormatName((UINT)format, buf, 512));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   852
    jstring name = JNU_NewStringPlatform(env, buf);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   853
    delete [] buf;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   854
    if (name == NULL) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   855
        throw std::bad_alloc();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   856
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   857
    return name;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   858
90ce3da70b43 Initial load
duke
parents:
diff changeset
   859
    CATCH_BAD_ALLOC_RET(NULL);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   860
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   861
90ce3da70b43 Initial load
duke
parents:
diff changeset
   862
/*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   863
 * Class:     sun_awt_windows_WToolkitThreadBlockedHandler
90ce3da70b43 Initial load
duke
parents:
diff changeset
   864
 * Method:    startSecondaryEventLoop
90ce3da70b43 Initial load
duke
parents:
diff changeset
   865
 * Signature: ()V;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   866
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   867
JNIEXPORT void JNICALL
90ce3da70b43 Initial load
duke
parents:
diff changeset
   868
Java_sun_awt_windows_WToolkitThreadBlockedHandler_startSecondaryEventLoop(JNIEnv *env, jclass)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   869
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
   870
    TRY;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   871
90ce3da70b43 Initial load
duke
parents:
diff changeset
   872
    AwtDataTransferer::SecondaryMessageLoop();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   873
90ce3da70b43 Initial load
duke
parents:
diff changeset
   874
    CATCH_BAD_ALLOC;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   875
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   876
90ce3da70b43 Initial load
duke
parents:
diff changeset
   877
}