jobject AwtMenuItem::GetFontMetrics(JNIEnv *env, jobject font) { static jobject toolkit = NULL; if (toolkit == NULL) { if (env->PushLocalFrame(2) < 0) return NULL; jclass cls = env->FindClass("java/awt/Toolkit"); jobject toolkitLocal = env->CallStaticObjectMethod(cls, AwtToolkit::getDefaultToolkitMID); toolkit = env->NewGlobalRef(toolkitLocal); DASSERT(!safe_ExceptionOccurred(env)); env->PopLocalFrame(0); } /* JNU_PrintClass(env, "toolkit", toolkit); JNU_PrintClass(env, "font", font); jclass cls = env->FindClass("java/awt/Toolkit"); jmethodID mid = env->GetMethodID(cls, "getFontMetrics", "(Ljava/awt/Font;)Ljava/awt/FontMetrics;"); jstring fontName = (jstring)JNU_CallMethodByName(env, 0,font, "getName", "()Ljava/lang/String;").l; JNU_PrintString(env, "font name", fontName); fprintf(stderr, "mid: %x\n", mid); fprintf(stderr, "cached mid: %x\n", AwtToolkit::getFontMetricsMID); DASSERT(!safe_ExceptionOccurred(env)); */ jobject fontMetrics = env->CallObjectMethod(toolkit, AwtToolkit::getFontMetricsMID, font); DASSERT(!safe_ExceptionOccurred(env)); return fontMetrics; }
void AwtObject::SendEvent(jobject event) { JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); #ifdef DEBUG if (reportEvents) { jstring eventStr = JNU_ToString(env, event); DASSERT(!safe_ExceptionOccurred(env)); jstring targetStr = (jstring)JNU_CallMethodByName(env, NULL, GetTarget(env),"getName", "()Ljava/lang/String;").l; DASSERT(!safe_ExceptionOccurred(env)); printf("Posting %S to %S\n", TO_WSTRING(eventStr), TO_WSTRING(targetStr)); } #endif /* Post event to the system EventQueue. */ JNU_CallMethodByName(env, NULL, GetPeer(env), "postEvent", "(Ljava/awt/AWTEvent;)V", event); { jthrowable exc = safe_ExceptionOccurred(env); if (exc) { env->DeleteLocalRef(exc); env->ExceptionDescribe(); } } DASSERT(!safe_ExceptionOccurred(env)); }
/* Execute a callback to the associated Java peer. */ void AwtObject::DoCallback(const char* methodName, const char* methodSig, ...) { JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); /* don't callback during the create & initialization process */ if (m_peerObject != NULL && m_callbacksEnabled) { va_list args; va_start(args, methodSig); #ifdef DEBUG if (reportEvents) { jstring targetStr = (jstring)JNU_CallMethodByName(env, NULL, GetTarget(env), "getName", "()Ljava/lang/String;").l; DASSERT(!safe_ExceptionOccurred(env)); printf("Posting %s%s method to %S\n", methodName, methodSig, TO_WSTRING(targetStr)); } #endif /* caching would do much good here */ JNU_CallMethodByNameV(env, NULL, GetPeer(env), methodName, methodSig, args); { jthrowable exc = safe_ExceptionOccurred(env); if (exc) { env->DeleteLocalRef(exc); env->ExceptionDescribe(); env->ExceptionClear(); } } DASSERT(!safe_ExceptionOccurred(env)); va_end(args); } }
/* * Class: sun_awt_windows_WInputMethodDescriptor * Method: getNativeAvailableLocales * Signature: ()[Ljava/util/Locale; */ JNIEXPORT jobjectArray JNICALL Java_sun_awt_windows_WInputMethodDescriptor_getNativeAvailableLocales (JNIEnv *env, jclass self) { TRY; // get list of available HKLs int layoutCount = ::GetKeyboardLayoutList(0, NULL); HKL FAR * hKLList = (HKL FAR *)safe_Malloc(sizeof(HKL)*layoutCount); DASSERT(!safe_ExceptionOccurred(env)); ::GetKeyboardLayoutList(layoutCount, hKLList); // get list of Java locale names while getting rid of duplicates int srcIndex = 0; int destIndex = 0; int javaLocaleNameCount = 0; int current = 0; const char ** javaLocaleNames = (const char **)safe_Malloc(sizeof(char *)*layoutCount); DASSERT(!safe_ExceptionOccurred(env)); for (; srcIndex < layoutCount; srcIndex++) { const char * srcLocaleName = getJavaIDFromLangID(LOWORD(hKLList[srcIndex])); if (srcLocaleName == NULL) { // could not find corresponding Java locale name for this HKL. continue; } for (current = 0; current < destIndex; current++) { if (strcmp(javaLocaleNames[current], srcLocaleName) == 0) { // duplicated. ignore this HKL break; } } if (current == destIndex) { javaLocaleNameCount++; destIndex++; javaLocaleNames[current] = srcLocaleName; } } // convert it to an array of Java locale objects jclass localeClass = env->FindClass("java/util/Locale"); jobjectArray locales = env->NewObjectArray(javaLocaleNameCount, localeClass, NULL); for (current = 0; current < javaLocaleNameCount; current++) { env->SetObjectArrayElement(locales, current, CreateLocaleObject(env, javaLocaleNames[current])); } DASSERT(!safe_ExceptionOccurred(env)); env->DeleteLocalRef(localeClass); free(hKLList); free(javaLocaleNames); return locales; CATCH_BAD_ALLOC_RET(NULL); }
void AwtScrollPane::SetInsets(JNIEnv *env) { RECT outside; RECT inside; ::GetWindowRect(GetHWnd(), &outside); ::GetClientRect(GetHWnd(), &inside); ::MapWindowPoints(GetHWnd(), 0, (LPPOINT)&inside, 2); if (env->EnsureLocalCapacity(1) < 0) { return; } jobject insets = (env)->GetObjectField(GetPeer(env), AwtPanel::insets_ID); DASSERT(!safe_ExceptionOccurred(env)); if (insets != NULL && (inside.top-outside.top) != 0) { (env)->SetIntField(insets, AwtInsets::topID, inside.top - outside.top); (env)->SetIntField(insets, AwtInsets::leftID, inside.left - outside.left); (env)->SetIntField(insets, AwtInsets::bottomID, outside.bottom - inside.bottom); (env)->SetIntField(insets, AwtInsets::rightID, outside.right - inside.right); } env->DeleteLocalRef(insets); }
jbyteArray AwtDataTransferer::ConvertData(JNIEnv* env, jobject source, jobject contents, jlong format, jobject formatMap) { jobject transferer = GetDataTransferer(env); if (!JNU_IsNull(env, transferer)) { jbyteArray ret = NULL; DECLARE_OBJECT_JAVA_METHOD(convertDataMethodID, dataTransfererClazz, "convertData", "(Ljava/lang/Object;Ljava/awt/datatransfer/Transferable;JLjava/util/Map;Z)[B"); ret = (jbyteArray)env->CallObjectMethod(transferer, convertDataMethodID, source, contents, format, formatMap, AwtToolkit::IsMainThread()); if (!JNU_IsNull(env, safe_ExceptionOccurred(env))) { env->ExceptionDescribe(); env->ExceptionClear(); } env->DeleteLocalRef(transferer); return ret; } else { return NULL; } }
/* * Class: sun_awt_Win32GraphicsConfig * Method: getBounds * Signature: ()Ljava/awt/Rectangle */ JNIEXPORT jobject JNICALL Java_sun_awt_Win32GraphicsConfig_getBounds(JNIEnv *env, jobject thisobj, jint screen) { jclass clazz; jmethodID mid; jobject bounds = NULL; clazz = env->FindClass("java/awt/Rectangle"); mid = env->GetMethodID(clazz, "<init>", "(IIII)V"); if (mid != 0) { RECT rRW = {0,0,0,0}; if( TRUE == ::MonitorBounds(AwtWin32GraphicsDevice::GetMonitor(screen), &rRW) ) { bounds = env->NewObject(clazz, mid, rRW.left, rRW.top, rRW.right - rRW.left, rRW.bottom - rRW.top); } else { // 4910760 - don't return a null bounds, return the bounds of the // primary screen bounds = env->NewObject(clazz, mid, 0, 0, ::GetSystemMetrics(SM_CXSCREEN), ::GetSystemMetrics(SM_CYSCREEN)); } if (safe_ExceptionOccurred(env)) { return 0; } } return bounds; }
int AwtMenuBar::CountItem(jobject menuBar) { JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); jint nCount = env->CallIntMethod(menuBar, AwtMenuBar::getMenuCountMID); DASSERT(!safe_ExceptionOccurred(env)); return nCount; }
/* * Return the peer associated with some target. This information is * maintained in a hashtable at the java level. */ jobject AwtObject::GetPeerForTarget(JNIEnv *env, jobject target) { jobject peer = GetPeer(env); jobject result = env->CallObjectMethod(peer, AwtObject::getPeerForTargetMID, target); DASSERT(!safe_ExceptionOccurred(env)); return result; }
/* * Return the peer associated with some target. This information is * maintained in a hashtable at the java level. */ jobject AwtObject::GetPeerForTarget(JNIEnv *env, jobject target) { jobject result = env->CallStaticObjectMethod(AwtObject::wObjectPeerClass, AwtObject::getPeerForTargetMID, target); DASSERT(!safe_ExceptionOccurred(env)); return result; }
/* * Class: sun_awt_windows_WComponentPeer * Method: handleEvent * Signature: (Lsun/awt/windows/WComponentPeer;Ljava/awt/AWTEvent;)V */ JNIEXPORT void JNICALL Java_sun_awt_windows_WInputMethod_handleNativeIMEEvent(JNIEnv *env, jobject self, jobject peer, jobject event) { TRY; PDATA pData; JNI_CHECK_PEER_RETURN(peer); AwtComponent* p = (AwtComponent *)pData; JNI_CHECK_NULL_RETURN(event, "null AWTEvent"); if (env->EnsureLocalCapacity(1) < 0) { return; } jbyteArray bdata = (jbyteArray)(env)->GetObjectField(event, AwtAWTEvent::bdataID); if (bdata == 0) { return; } MSG msg; (env)->GetByteArrayRegion(bdata, 0, sizeof(MSG), (jbyte *)&msg); (env)->DeleteLocalRef(bdata); BOOL isConsumed = (BOOL)(env)->GetBooleanField(event, AwtAWTEvent::consumedID); int id = (env)->GetIntField(event, AwtAWTEvent::idID); DASSERT(!safe_ExceptionOccurred(env)); if (isConsumed || p==NULL) return; if (id >= java_awt_event_InputMethodEvent_INPUT_METHOD_FIRST && id <= java_awt_event_InputMethodEvent_INPUT_METHOD_LAST) { long modifiers = p->GetJavaModifiers(); if (msg.message==WM_CHAR || msg.message==WM_SYSCHAR) { WCHAR unicodeChar = L'\0'; unicodeChar = (WCHAR)msg.wParam; p->SendKeyEvent(java_awt_event_KeyEvent_KEY_TYPED, 0, //to be fixed nowMillis(), java_awt_event_KeyEvent_CHAR_UNDEFINED, unicodeChar, modifiers, java_awt_event_KeyEvent_KEY_LOCATION_UNKNOWN, (jlong)0, &msg); } else { MSG* pCopiedMsg = new MSG; *pCopiedMsg = msg; p->SendMessage(WM_AWT_HANDLE_EVENT, (WPARAM) FALSE, (LPARAM) pCopiedMsg); } (env)->SetBooleanField(event, AwtAWTEvent::consumedID, JNI_TRUE); } CATCH_BAD_ALLOC; }
/* * Class: sun_awt_windows_WColor * Method: getDefaultColor * Signature: (I)Ljava/awt/Color; */ JNIEXPORT jobject JNICALL Java_sun_awt_windows_WColor_getDefaultColor(JNIEnv *env, jclass cls, jint index) { TRY; int iColor = 0; switch(index) { case sun_awt_windows_WColor_WINDOW_BKGND: iColor = COLOR_WINDOW; break; case sun_awt_windows_WColor_WINDOW_TEXT: iColor = COLOR_WINDOWTEXT; break; case sun_awt_windows_WColor_FRAME: iColor = COLOR_WINDOWFRAME; break; case sun_awt_windows_WColor_SCROLLBAR: iColor = COLOR_SCROLLBAR; break; case sun_awt_windows_WColor_MENU_BKGND: iColor = COLOR_MENU; break; case sun_awt_windows_WColor_MENU_TEXT: iColor = COLOR_MENUTEXT; break; case sun_awt_windows_WColor_BUTTON_BKGND: iColor = (IS_NT) ? COLOR_BTNFACE : COLOR_3DFACE; break; case sun_awt_windows_WColor_BUTTON_TEXT: iColor = COLOR_BTNTEXT; break; case sun_awt_windows_WColor_HIGHLIGHT: iColor = COLOR_HIGHLIGHT; break; default: return NULL; } DWORD c = ::GetSysColor(iColor); jobject wColor = JNU_NewObjectByName(env, "java/awt/Color", "(III)V", GetRValue(c), GetGValue(c), GetBValue(c)); DASSERT(!safe_ExceptionOccurred(env)); return wColor; CATCH_BAD_ALLOC_RET(NULL); }
void AwtClipboard::WmDrawClipboard(JNIEnv *env, WPARAM wParam, LPARAM lParam) { if (skipInitialWmDrawClipboardMsg) { // skipping the first contents change notification as it comes // immediately after registering the clipboard viewer window // and it is not caused by an actual contents change. skipInitialWmDrawClipboardMsg = FALSE; return; } if (theCurrentClipboard != NULL) { env->CallVoidMethod(theCurrentClipboard, handleContentsChangedMID); DASSERT(!safe_ExceptionOccurred(env)); } ::SendMessage(hwndNextViewer, WM_DRAWCLIPBOARD, wParam, lParam); }
void AwtChoice::VerifyState() { if (AwtToolkit::GetInstance().VerifyComponents() == FALSE) { return; } if (m_callbacksEnabled == FALSE) { /* Component is not fully setup yet. */ return; } AwtComponent::VerifyState(); JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); if (env->PushLocalFrame(1) < 0) return; jobject target = GetTarget(env); // To avoid possibly running client code on the toolkit thread, don't // do the following checks if we're running on the toolkit thread. if (AwtToolkit::MainThread() != ::GetCurrentThreadId()) { // Compare number of items. int nTargetItems = JNU_CallMethodByName(env, NULL, target, "countItems", "()I").i; DASSERT(!safe_ExceptionOccurred(env)); int nPeerItems = (int)::SendMessage(GetHWnd(), CB_GETCOUNT, 0, 0); DASSERT(nTargetItems == nPeerItems); // Compare selection int targetIndex = JNU_CallMethodByName(env, NULL, target, "getSelectedIndex", "()I").i; DASSERT(!safe_ExceptionOccurred(env)); int peerCurSel = (int)::SendMessage(GetHWnd(), CB_GETCURSEL, 0, 0); DASSERT(targetIndex == peerCurSel); } env->PopLocalFrame(0); }
void AwtScrollPane::PostScrollEvent(int orient, int scrollCode, int pos) { if (scrollCode == SB_ENDSCROLL) { return; } // convert Windows scroll bar ident to peer ident jint jorient; if (orient == SB_VERT) { jorient = java_awt_Adjustable_VERTICAL; } else if (orient == SB_HORZ) { jorient = java_awt_Adjustable_HORIZONTAL; } else { DASSERT(FALSE); return; } // convert Windows scroll code to adjustment type and isAdjusting status jint jscrollcode; jboolean jadjusting = JNI_FALSE; switch (scrollCode) { case SB_LINEUP: jscrollcode = java_awt_event_AdjustmentEvent_UNIT_DECREMENT; break; case SB_LINEDOWN: jscrollcode = java_awt_event_AdjustmentEvent_UNIT_INCREMENT; break; case SB_PAGEUP: jscrollcode = java_awt_event_AdjustmentEvent_BLOCK_DECREMENT; break; case SB_PAGEDOWN: jscrollcode = java_awt_event_AdjustmentEvent_BLOCK_INCREMENT; break; case SB_THUMBTRACK: jscrollcode = java_awt_event_AdjustmentEvent_TRACK; jadjusting = JNI_TRUE; break; case SB_THUMBPOSITION: jscrollcode = java_awt_event_AdjustmentEvent_TRACK; break; default: DASSERT(FALSE); return; } JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); env->CallVoidMethod(GetPeer(env), AwtScrollPane::postScrollEventID, jorient, jscrollcode, (jint)pos, jadjusting); DASSERT(!safe_ExceptionOccurred(env)); }
/* * There currently is no good place to cache java.awt.Dimension field * ids. If this method gets called a lot, one such place should be found. * -- br 07/18/97. */ jobject AwtList::PreferredItemSize(JNIEnv *env) { jobject peer = GetPeer(env); jobject dimension = JNU_CallMethodByName(env, NULL, peer, "preferredSize", "(I)Ljava/awt/Dimension;", 1).l; DASSERT(!safe_ExceptionOccurred(env)); if (dimension == NULL) { return NULL; } /* This size is too big for each item height. */ (env)->SetIntField(dimension, AwtDimension::heightID, GetFontHeight(env)); return dimension; }
jobject AwtChoice::PreferredItemSize(JNIEnv *env) { jobject dimension = JNU_CallMethodByName(env, NULL, GetPeer(env), "preferredSize", "()Ljava/awt/Dimension;").l; DASSERT(!safe_ExceptionOccurred(env)); if (dimension == NULL) { return NULL; } /* This size is window size of choice and it's too big for each * drop down item height. */ env->SetIntField(dimension, AwtDimension::heightID, GetFontHeight(env)); return dimension; }
/* * Class: sun_awt_windows_WInputMethod * Method: setNativeLocale * Signature: (Ljava/lang/String;Z)Z */ JNIEXPORT jboolean JNICALL Java_sun_awt_windows_WInputMethod_setNativeLocale (JNIEnv *env, jclass cls, jstring localeString, jboolean onActivate) { TRY; // check if current language ID is the requested one. Note that the // current language ID (returned from 'getJavaIDFromLangID') is in // ASCII encoding, so we use 'GetStringUTFChars' to retrieve requested // language ID from the 'localeString' object. const char * current = getJavaIDFromLangID(AwtComponent::GetInputLanguage()); jboolean isCopy; const char * requested = env->GetStringUTFChars(localeString, &isCopy); if ((current != NULL) && (strcmp(current, requested) == 0)) { env->ReleaseStringUTFChars(localeString, requested); return JNI_TRUE; } // get list of available HKLs. Adding the user's preferred layout on top of the layout // list which is returned by GetKeyboardLayoutList ensures to match first when // looking up suitable layout. int layoutCount = ::GetKeyboardLayoutList(0, NULL) + 1; // +1 for user's preferred HKL HKL FAR * hKLList = (HKL FAR *)safe_Malloc(sizeof(HKL)*layoutCount); DASSERT(!safe_ExceptionOccurred(env)); ::GetKeyboardLayoutList(layoutCount - 1, &(hKLList[1])); hKLList[0] = getDefaultKeyboardLayout(); // put user's preferred layout on top of the list // lookup matching LangID jboolean retValue = JNI_FALSE; for (int i = 0; i < layoutCount; i++) { const char * supported = getJavaIDFromLangID(LOWORD(hKLList[i])); if ((supported != NULL) && (strcmp(supported, requested) == 0)) { // use special message to call ActivateKeyboardLayout() in main thread. if (AwtToolkit::GetInstance().SendMessage(WM_AWT_ACTIVATEKEYBOARDLAYOUT, (WPARAM)onActivate, (LPARAM)hKLList[i])) { //also need to change the same keyboard layout for the Java AWT-EventQueue thread AwtToolkit::activateKeyboardLayout(hKLList[i]); retValue = JNI_TRUE; } break; } } env->ReleaseStringUTFChars(localeString, requested); free(hKLList); return retValue; CATCH_BAD_ALLOC_RET(JNI_FALSE); }
void AwtScrollPane::VerifyState() { JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); if (env->EnsureLocalCapacity(3) < 0) { return; } if (AwtToolkit::GetInstance().VerifyComponents() == FALSE) { return; } if (m_callbacksEnabled == FALSE) { /* Component is not fully setup yet. */ return; } AwtComponent::VerifyState(); jobject target = AwtObject::GetTarget(env); jobject child = JNU_CallMethodByName(env, NULL, GetPeer(env), "getScrollSchild", "()Ljava/awt/Component;").l; DASSERT(!safe_ExceptionOccurred(env)); if (child != NULL) { jobject childPeer = (env)->GetObjectField(child, AwtComponent::peerID); PDATA pData; JNI_CHECK_PEER_RETURN(childPeer); AwtComponent* awtChild = (AwtComponent *)pData; /* Verify child window is positioned correctly. */ RECT rect, childRect; ::GetClientRect(GetHWnd(), &rect); ::MapWindowPoints(GetHWnd(), 0, (LPPOINT)&rect, 2); ::GetWindowRect(awtChild->GetHWnd(), &childRect); DASSERT(childRect.left <= rect.left && childRect.top <= rect.top); env->DeleteLocalRef(childPeer); } env->DeleteLocalRef(target); env->DeleteLocalRef(child); }
/* * Class: sun_awt_windows_WScrollPanePeer * Method: setTypedValue * Signature: (Ljava/awt/ScrollPaneAdjustable;II)V */ JNIEXPORT void JNICALL Java_sun_awt_windows_WScrollPanePeer_setTypedValue(JNIEnv *env, jobject peer, jobject adjustable, jint value, jint type) { // need this global ref to make the class unloadable (see 6500204) static jclass scrollPaneAdj; static jmethodID setTypedValueMID = 0; if (setTypedValueMID == NULL) { jclass clazz = env->FindClass("java/awt/ScrollPaneAdjustable"); if (safe_ExceptionOccurred(env)) { env->ExceptionDescribe(); env->ExceptionClear(); } setTypedValueMID = env->GetMethodID(clazz, "setTypedValue", "(II)V"); scrollPaneAdj = (jclass) env->NewGlobalRef(clazz); env->DeleteLocalRef(clazz); DASSERT(setTypedValueMID != NULL); } env->CallVoidMethod(adjustable, setTypedValueMID, value, type); }
AwtMenuItem* AwtMenuBar::GetItem(jobject target, long index) { JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); if (env->EnsureLocalCapacity(2) < 0) { return NULL; } jobject menu = env->CallObjectMethod(target, AwtMenuBar::getMenuMID,index); if (!menu) return NULL; // menu item was removed concurrently DASSERT(!safe_ExceptionOccurred(env)); jobject menuItemPeer = GetPeerForTarget(env, menu); PDATA pData; JNI_CHECK_PEER_GOTO(menuItemPeer, done); AwtMenuItem* awtMenuItem = (AwtMenuItem*)pData; done: env->DeleteLocalRef(menu); env->DeleteLocalRef(menuItemPeer); return awtMenuItem; }
/* * Create a Java locale object from its name string */ jobject CreateLocaleObject(JNIEnv *env, const char * name) { TRY; // get language, country, variant information char * language = (char *)safe_Malloc(strlen(name) + 1); char * country; char * variant; DASSERT(!safe_ExceptionOccurred(env)); strcpy(language, name); for (country = language; *country != '_' && *country != '\0'; country++); if (*country == '_') { *country++ = '\0'; for (variant = country; *variant != '_' && *variant != '\0'; variant++); if (*variant == '_') { *variant++ = '\0'; } } else { variant = country; } // create Locale object jobject langObj = env->NewStringUTF(language); jobject ctryObj = env->NewStringUTF(country); jobject vrntObj = env->NewStringUTF(variant); jobject localeObj = JNU_NewObjectByName(env, "java/util/Locale", "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V", langObj, ctryObj, vrntObj); free(language); env->DeleteLocalRef(langObj); env->DeleteLocalRef(ctryObj); env->DeleteLocalRef(vrntObj); return localeObj; CATCH_BAD_ALLOC_RET(NULL); }
jobject AwtDataTransferer::ConcatData(JNIEnv* env, jobject obj1, jobject obj2) { jobject transferer = GetDataTransferer(env); if (!JNU_IsNull(env, transferer)) { jobject ret = NULL; DECLARE_OBJECT_JAVA_METHOD(concatDataMethodID, dataTransfererClazz, "concatData", "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;"); ret = env->CallObjectMethod(transferer, concatDataMethodID, obj1, obj2); if (!JNU_IsNull(env, safe_ExceptionOccurred(env))) { env->ExceptionDescribe(); env->ExceptionClear(); } env->DeleteLocalRef(transferer); return ret; } else { return NULL; } }
AwtChoice* AwtChoice::Create(jobject peer, jobject parent) { JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); jobject target = NULL; AwtChoice* c = NULL; RECT rc; try { if (env->EnsureLocalCapacity(1) < 0) { return NULL; } AwtCanvas* awtParent; JNI_CHECK_NULL_GOTO(parent, "null parent", done); awtParent = (AwtCanvas*)JNI_GET_PDATA(parent); JNI_CHECK_NULL_GOTO(awtParent, "null awtParent", done); target = env->GetObjectField(peer, AwtObject::targetID); JNI_CHECK_NULL_GOTO(target, "null target", done); c = new AwtChoice(); { DWORD style = WS_CHILD | WS_CLIPSIBLINGS | WS_VSCROLL | CBS_DROPDOWNLIST | CBS_OWNERDRAWFIXED; DWORD exStyle = 0; if (GetRTL()) { exStyle |= WS_EX_RIGHT | WS_EX_LEFTSCROLLBAR; if (GetRTLReadingOrder()) exStyle |= WS_EX_RTLREADING; } /* * In OWNER_DRAW, the size of the edit control part of the * choice must be determinded in its creation, when the parent * cannot get the choice's instance from its handle. So * record the pair of the ID and the instance of the choice. */ UINT myId = awtParent->CreateControlID(); DASSERT(myId > 0); c->m_myControlID = myId; awtParent->PushChild(myId, c); jint x = env->GetIntField(target, AwtComponent::xID); jint y = env->GetIntField(target, AwtComponent::yID); jint width = env->GetIntField(target, AwtComponent::widthID); jint height = env->GetIntField(target, AwtComponent::heightID); jobject dimension = JNU_CallMethodByName(env, NULL, peer, "preferredSize", "()Ljava/awt/Dimension;").l; DASSERT(!safe_ExceptionOccurred(env)); if (dimension != NULL && width == 0) { width = env->GetIntField(dimension, AwtDimension::widthID); } c->CreateHWnd(env, L"", style, exStyle, x, y, width, height, awtParent->GetHWnd(), reinterpret_cast<HMENU>(static_cast<INT_PTR>(myId)), ::GetSysColor(COLOR_WINDOWTEXT), ::GetSysColor(COLOR_WINDOW), peer); /* suppress inheriting parent's color. */ c->m_backgroundColorSet = TRUE; c->UpdateBackground(env, target); /* Bug 4255631 Solaris: Size returned by Choice.getSize() does not match * actual size * Fix: Set the Choice to its actual size in the component. */ ::GetClientRect(c->GetHWnd(), &rc); env->SetIntField(target, AwtComponent::widthID, (jint) rc.right); env->SetIntField(target, AwtComponent::heightID, (jint) rc.bottom); env->DeleteLocalRef(dimension); } } catch (...) { env->DeleteLocalRef(target); throw; } done: env->DeleteLocalRef(target); return c; }
void AwtClipboard::LostOwnership(JNIEnv *env) { if (theCurrentClipboard != NULL) { env->CallVoidMethod(theCurrentClipboard, lostSelectionOwnershipMID); DASSERT(!safe_ExceptionOccurred(env)); } }
/* * Class: sun_awt_windows_WClipboard * Method: getClipboardData * Signature: (J)[B */ JNIEXPORT jbyteArray JNICALL Java_sun_awt_windows_WClipboard_getClipboardData (JNIEnv *env, jobject self, jlong format) { TRY; DASSERT(::GetOpenClipboardWindow() == AwtToolkit::GetInstance().GetHWnd()); HANDLE handle = ::GetClipboardData((UINT)format); if (handle == NULL) { JNU_ThrowIOException(env, "system clipboard data unavailable"); return NULL; } jbyteArray bytes = NULL; jbyteArray paletteData = NULL; switch (format) { case CF_ENHMETAFILE: case CF_METAFILEPICT: { HENHMETAFILE hemf = NULL; if (format == CF_METAFILEPICT) { HMETAFILEPICT hMetaFilePict = (HMETAFILEPICT)handle; LPMETAFILEPICT lpMetaFilePict = (LPMETAFILEPICT)::GlobalLock(hMetaFilePict); UINT uSize = ::GetMetaFileBitsEx(lpMetaFilePict->hMF, 0, NULL); DASSERT(uSize != 0); try { LPBYTE lpMfBits = (LPBYTE)safe_Malloc(uSize); VERIFY(::GetMetaFileBitsEx(lpMetaFilePict->hMF, uSize, lpMfBits) == uSize); hemf = ::SetWinMetaFileBits(uSize, lpMfBits, NULL, lpMetaFilePict); free(lpMfBits); if (hemf == NULL) { ::GlobalUnlock(hMetaFilePict); JNU_ThrowIOException(env, "failed to get system clipboard data"); return NULL; } } catch (...) { ::GlobalUnlock(hMetaFilePict); throw; } ::GlobalUnlock(hMetaFilePict); } else { hemf = (HENHMETAFILE)handle; } UINT uEmfSize = ::GetEnhMetaFileBits(hemf, 0, NULL); if (uEmfSize == 0) { JNU_ThrowIOException(env, "cannot retrieve metafile bits"); return NULL; } bytes = env->NewByteArray(uEmfSize); if (bytes == NULL) { throw std::bad_alloc(); } LPBYTE lpbEmfBuffer = (LPBYTE)env->GetPrimitiveArrayCritical(bytes, NULL); if (lpbEmfBuffer == NULL) { env->DeleteLocalRef(bytes); throw std::bad_alloc(); } VERIFY(::GetEnhMetaFileBits(hemf, uEmfSize, lpbEmfBuffer) == uEmfSize); env->ReleasePrimitiveArrayCritical(bytes, lpbEmfBuffer, 0); paletteData = AwtDataTransferer::GetPaletteBytes(hemf, OBJ_ENHMETAFILE, FALSE); break; } case CF_LOCALE: { LCID *lcid = (LCID *)::GlobalLock(handle); if (lcid == NULL) { JNU_ThrowIOException(env, "invalid LCID"); return NULL; } try { bytes = AwtDataTransferer::LCIDToTextEncoding(env, *lcid); } catch (...) { ::GlobalUnlock(handle); throw; } ::GlobalUnlock(handle); break; } default: { ::SetLastError(0); // clear error // Warning C4244. // Cast SIZE_T (__int64 on 64-bit/unsigned int on 32-bit) // to jsize (long). SIZE_T globalSize = ::GlobalSize(handle); jsize size = (globalSize <= INT_MAX) ? (jsize)globalSize : INT_MAX; if (::GetLastError() != 0) { JNU_ThrowIOException(env, "invalid global memory block handle"); return NULL; } bytes = env->NewByteArray(size); if (bytes == NULL) { throw std::bad_alloc(); } if (size != 0) { LPVOID data = ::GlobalLock(handle); env->SetByteArrayRegion(bytes, 0, size, (jbyte *)data); ::GlobalUnlock(handle); } break; } } switch (format) { case CF_ENHMETAFILE: case CF_METAFILEPICT: case CF_DIB: { if (JNU_IsNull(env, paletteData)) { HPALETTE hPalette = (HPALETTE)::GetClipboardData(CF_PALETTE); paletteData = AwtDataTransferer::GetPaletteBytes(hPalette, OBJ_PAL, TRUE); } DASSERT(!JNU_IsNull(env, paletteData) && !JNU_IsNull(env, bytes)); jbyteArray concat = (jbyteArray)AwtDataTransferer::ConcatData(env, paletteData, bytes); if (!JNU_IsNull(env, safe_ExceptionOccurred(env))) { env->ExceptionDescribe(); env->ExceptionClear(); env->DeleteLocalRef(bytes); env->DeleteLocalRef(paletteData); return NULL; } env->DeleteLocalRef(bytes); env->DeleteLocalRef(paletteData); bytes = concat; break; } } return bytes; CATCH_BAD_ALLOC_RET(NULL); }
/* * Create a new AwtCanvas object and window. */ AwtCanvas* AwtCanvas::Create(jobject self, jobject hParent) { TRY; JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); jobject target = NULL; AwtCanvas *canvas = NULL; try { if (env->EnsureLocalCapacity(1) < 0) { return NULL; } AwtComponent* parent; JNI_CHECK_NULL_GOTO(hParent, "null hParent", done); parent = (AwtComponent*)JNI_GET_PDATA(hParent); JNI_CHECK_NULL_GOTO(parent, "null parent", done); target = env->GetObjectField(self, AwtObject::targetID); JNI_CHECK_NULL_GOTO(target, "null target", done); canvas = new AwtCanvas(); { jint x = env->GetIntField(target, AwtComponent::xID); jint y = env->GetIntField(target, AwtComponent::yID); jint width = env->GetIntField(target, AwtComponent::widthID); jint height = env->GetIntField(target, AwtComponent::heightID); canvas->CreateHWnd(env, L"", WS_CHILD | WS_CLIPCHILDREN | WS_CLIPSIBLINGS, 0, x, y, width, height, parent->GetHWnd(), NULL, ::GetSysColor(COLOR_WINDOWTEXT), ::GetSysColor(COLOR_WINDOW), self); // Set the pixel format of the HWND if a GraphicsConfiguration // was provided to the Canvas constructor. jclass canvasClass = env->FindClass("java/awt/Canvas"); if ( env->IsInstanceOf( target, canvasClass ) ) { // Get GraphicsConfig from our target jobject graphicsConfig = env->GetObjectField(target, AwtComponent::graphicsConfigID); if (graphicsConfig != NULL) { jclass win32cls = env->FindClass("sun/awt/Win32GraphicsConfig"); DASSERT (win32cls != NULL); if ( env->IsInstanceOf( graphicsConfig, win32cls ) ) { // Get the visual ID member from our GC jint visual = env->GetIntField(graphicsConfig, AwtWin32GraphicsConfig::win32GCVisualID); if (visual > 0) { HDC hdc = ::GetDC(canvas->m_hwnd); // Set our pixel format PIXELFORMATDESCRIPTOR pfd; BOOL ret = ::SetPixelFormat(hdc, (int)visual, &pfd); ::ReleaseDC(canvas->m_hwnd, hdc); //Since a GraphicsConfiguration was specified, we should //throw an exception if the PixelFormat couldn't be set. if (ret == FALSE) { DASSERT(!safe_ExceptionOccurred(env)); jclass excCls = env->FindClass( "java/lang/RuntimeException"); DASSERT(excCls); env->ExceptionClear(); env->ThrowNew(excCls, "\nUnable to set Pixel format on Canvas"); env->DeleteLocalRef(target); return canvas; } } } } } } } catch (...) { env->DeleteLocalRef(target); throw; } done: env->DeleteLocalRef(target); return canvas; CATCH_BAD_ALLOC_RET(0); }
/* Retrieve the context data from the current IMC. Params: HIMC hIMC - the input method context, must NOT be NULL LPARAMS flags - message param to WM_IME_COMPOSITION. Returns 0 if success. */ int AwtInputTextInfor::GetContextData(HIMC hIMC, const LPARAM flags) { DASSERT(hIMC != 0); m_flags = flags; // Based on different flags received, we use different GCS_XXX from the // GCS_INDEX array. int startIndex = 0, endIndex = 0; if (flags & GCS_COMPSTR) { startIndex = START_COMPSTR; endIndex = END_COMPSTR; /* For some window input method such as Chinese QuanPing, when the user * commits some text, the IMM sends WM_IME_COMPOSITION with GCS_COMPSTR/GCS_RESULTSTR. * So we have to extract the result string from IMC. For most of other cases, * m_pResultTextInfor is NULL and this is why we choose to have a pointer as its member * rather than having a list of the result string information. */ if (flags & GCS_RESULTSTR) { m_pResultTextInfor = new AwtInputTextInfor; m_pResultTextInfor->GetContextData(hIMC, GCS_RESULTSTR); } } else if (flags & GCS_RESULTSTR) { startIndex = START_RESULTSTR; endIndex = END_RESULTSTR; } else { // unknown flags. return -1; } /* Get the data from the input context */ LONG cbData[5] = {0}; LPVOID lpData[5] = {NULL}; for (int i = startIndex, j = 0; i <= endIndex; i++, j++) { cbData[j] = ::ImmGetCompositionString(hIMC, GCS_INDEX[i], NULL, 0); if (cbData[j] == 0) { lpData[j] = NULL; } else { LPBYTE lpTemp = new BYTE[cbData[j]]; cbData[j] = ::ImmGetCompositionString(hIMC, GCS_INDEX[i], lpTemp, cbData[j]); if (IMM_ERROR_GENERAL != cbData[j]) { lpData[j] = (LPVOID)lpTemp; } else { lpData[j] = NULL; return -1; } } } // Assign the context data m_cStrW = cbData[0]/WCHAR_SZ; m_lpStrW = (LPWSTR)lpData[0]; m_cReadStrW = cbData[1]/WCHAR_SZ; m_lpReadStrW = (LPWSTR)lpData[1]; m_cClauseW = cbData[2]/DWORD_SZ - 1; m_lpClauseW = (LPDWORD)lpData[2]; m_cReadClauseW = cbData[3]/DWORD_SZ - 1; m_lpReadClauseW = (LPDWORD)lpData[3]; if (cbData[4] > 0) { m_cAttrW = cbData[4]; m_lpAttrW = (LPBYTE)lpData[4]; } // Get the cursor position if (flags & GCS_COMPSTR) { m_cursorPosW = ::ImmGetCompositionString(hIMC, GCS_CURSORPOS, NULL, 0); } JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); if (m_cStrW > 0) { m_jtext = MakeJavaString(env, m_lpStrW, m_cStrW); JNU_CHECK_EXCEPTION_RETURN(env, -1); } // Merge the string if necessary if (m_pResultTextInfor != NULL) { jstring jresultText = m_pResultTextInfor->GetText(); if (m_jtext != NULL && jresultText != NULL) { jstring jMergedtext = (jstring)JNU_CallMethodByName(env, NULL, jresultText, "concat", "(Ljava/lang/String;)Ljava/lang/String;", m_jtext).l; DASSERT(!safe_ExceptionOccurred(env)); DASSERT(jMergedtext != NULL); env->DeleteLocalRef(m_jtext); m_jtext = jMergedtext; } else if (m_jtext == NULL && jresultText != NULL) { /* No composing text, assign the committed text to m_jtext */ m_jtext = (jstring)env->NewLocalRef(jresultText); } } return 0; }
void AwtFileDialog::Show(void *p) { JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); jobject peer; WCHAR unicodeChar = L' '; LPTSTR fileBuffer = NULL; LPTSTR currentDirectory = NULL; jint mode = 0; BOOL result = FALSE; DWORD dlgerr; jstring directory = NULL; jstring title = NULL; jstring file = NULL; jobject fileFilter = NULL; jobject target = NULL; jobject parent = NULL; AwtComponent* awtParent = NULL; jboolean multipleMode = JNI_FALSE; OPENFILENAME ofn; memset(&ofn, 0, sizeof(ofn)); /* * There's a situation (see bug 4906972) when InvokeFunction (by which this method is called) * returnes earlier than this method returnes. Probably it's caused due to ReplyMessage system call. * So for the avoidance of this mistiming we need to make new global reference here * (not local as it's used by the hook) and then manage it independently of the calling thread. */ peer = env->NewGlobalRef((jobject)p); try { DASSERT(peer); target = env->GetObjectField(peer, AwtObject::targetID); parent = env->GetObjectField(peer, AwtFileDialog::parentID); if (parent != NULL) { awtParent = (AwtComponent *)JNI_GET_PDATA(parent); } // DASSERT(awtParent); title = (jstring)(env)->GetObjectField(target, AwtDialog::titleID); HWND hwndOwner = awtParent ? awtParent->GetHWnd() : NULL; if (title == NULL || env->GetStringLength(title)==0) { title = JNU_NewStringPlatform(env, &unicodeChar); } JavaStringBuffer titleBuffer(env, title); directory = (jstring)env->GetObjectField(target, AwtFileDialog::dirID); JavaStringBuffer directoryBuffer(env, directory); multipleMode = env->CallBooleanMethod(peer, AwtFileDialog::isMultipleModeMID); UINT bufferLimit; if (multipleMode == JNI_TRUE) { bufferLimit = MULTIPLE_MODE_BUFFER_LIMIT; } else { bufferLimit = SINGLE_MODE_BUFFER_LIMIT; } LPTSTR fileBuffer = new TCHAR[bufferLimit]; memset(fileBuffer, 0, bufferLimit * sizeof(TCHAR)); file = (jstring)env->GetObjectField(target, AwtFileDialog::fileID); if (file != NULL) { LPCTSTR tmp = JNU_GetStringPlatformChars(env, file, NULL); _tcscpy(fileBuffer, tmp); JNU_ReleaseStringPlatformChars(env, file, tmp); } else { fileBuffer[0] = _T('\0'); } ofn.lStructSize = sizeof(ofn); ofn.lpstrFilter = s_fileFilterString; ofn.nFilterIndex = 1; /* Fix for 6488834. To disable Win32 native parent modality we have to set hwndOwner field to either NULL or some hidden window. For parentless dialogs we use NULL to show them in the taskbar, and for all other dialogs AwtToolkit's HWND is used. */ if (awtParent != NULL) { ofn.hwndOwner = AwtToolkit::GetInstance().GetHWnd(); } else { ofn.hwndOwner = NULL; } ofn.lpstrFile = fileBuffer; ofn.nMaxFile = bufferLimit; ofn.lpstrTitle = titleBuffer; ofn.lpstrInitialDir = directoryBuffer; ofn.Flags = OFN_LONGNAMES | OFN_OVERWRITEPROMPT | OFN_HIDEREADONLY | OFN_ENABLEHOOK | OFN_EXPLORER | OFN_ENABLESIZING; fileFilter = env->GetObjectField(peer, AwtFileDialog::fileFilterID); if (!JNU_IsNull(env,fileFilter)) { ofn.Flags |= OFN_ENABLEINCLUDENOTIFY; } ofn.lCustData = (LPARAM)peer; ofn.lpfnHook = (LPOFNHOOKPROC)FileDialogHookProc; if (multipleMode == JNI_TRUE) { ofn.Flags |= OFN_ALLOWMULTISELECT; } // Save current directory, so we can reset if it changes. currentDirectory = new TCHAR[MAX_PATH+1]; VERIFY(::GetCurrentDirectory(MAX_PATH, currentDirectory) > 0); mode = env->GetIntField(target, AwtFileDialog::modeID); AwtDialog::CheckInstallModalHook(); // show the Win32 file dialog if (mode == java_awt_FileDialog_LOAD) { result = AwtFileDialog::GetOpenFileName(&ofn); } else { result = AwtFileDialog::GetSaveFileName(&ofn); } // Fix for 4181310: FileDialog does not show up. // If the dialog is not shown because of invalid file name // replace the file name by empty string. if (!result) { dlgerr = ::CommDlgExtendedError(); if (dlgerr == FNERR_INVALIDFILENAME) { _tcscpy(fileBuffer, TEXT("")); if (mode == java_awt_FileDialog_LOAD) { result = AwtFileDialog::GetOpenFileName(&ofn); } else { result = AwtFileDialog::GetSaveFileName(&ofn); } } } AwtDialog::CheckUninstallModalHook(); DASSERT(env->GetLongField(peer, AwtComponent::hwndID) == 0L); AwtDialog::ModalActivateNextWindow(NULL, target, peer); VERIFY(::SetCurrentDirectory(currentDirectory)); // Report result to peer. if (result) { jint length = (jint)GetBufferLength(ofn.lpstrFile, ofn.nMaxFile); jcharArray jnames = env->NewCharArray(length); env->SetCharArrayRegion(jnames, 0, length, (jchar*)ofn.lpstrFile); env->CallVoidMethod(peer, AwtFileDialog::handleSelectedMID, jnames); env->DeleteLocalRef(jnames); } else { env->CallVoidMethod(peer, AwtFileDialog::handleCancelMID); } DASSERT(!safe_ExceptionOccurred(env)); } catch (...) { env->DeleteLocalRef(target); env->DeleteLocalRef(parent); env->DeleteLocalRef(title); env->DeleteLocalRef(directory); env->DeleteLocalRef(file); env->DeleteLocalRef(fileFilter); env->DeleteGlobalRef(peer); delete[] currentDirectory; if (ofn.lpstrFile) delete[] ofn.lpstrFile; throw; } env->DeleteLocalRef(target); env->DeleteLocalRef(parent); env->DeleteLocalRef(title); env->DeleteLocalRef(directory); env->DeleteLocalRef(file); env->DeleteLocalRef(fileFilter); env->DeleteGlobalRef(peer); delete[] currentDirectory; if (ofn.lpstrFile) delete[] ofn.lpstrFile; }