|
Java example source code file (awt_Window.cpp)
This example Java source code file (awt_Window.cpp) is included in the alvinalexander.com
"Java Source Code
Warehouse" project. The intent of this project is to help you "Learn
Java by Example" TM.
Learn more about this Java project at its project page.
The awt_Window.cpp Java example source code
/*
* Copyright (c) 1996, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
#include "awt.h"
#include <jlong.h>
#include "awt_Component.h"
#include "awt_Container.h"
#include "awt_Frame.h"
#include "awt_Dialog.h"
#include "awt_Insets.h"
#include "awt_Panel.h"
#include "awt_Toolkit.h"
#include "awt_Window.h"
#include "awt_Win32GraphicsDevice.h"
#include "awt_BitmapUtil.h"
#include "awt_IconCursor.h"
#include "ComCtl32Util.h"
#include "java_awt_Insets.h"
#include <java_awt_Container.h>
#include <java_awt_event_ComponentEvent.h>
#include "sun_awt_windows_WCanvasPeer.h"
#include <windowsx.h>
#if !defined(__int3264)
typedef __int32 LONG_PTR;
#endif // __int3264
// Used for Swing's Menu/Tooltip animation Support
const int UNSPECIFIED = 0;
const int TOOLTIP = 1;
const int MENU = 2;
const int SUBMENU = 3;
const int POPUPMENU = 4;
const int COMBOBOX_POPUP = 5;
const int TYPES_COUNT = 6;
jint windowTYPES[TYPES_COUNT];
/* IMPORTANT! Read the README.JNI file for notes on JNI converted AWT code.
*/
/***********************************************************************/
// struct for _SetAlwaysOnTop() method
struct SetAlwaysOnTopStruct {
jobject window;
jboolean value;
};
// struct for _SetTitle() method
struct SetTitleStruct {
jobject window;
jstring title;
};
// struct for _SetResizable() method
struct SetResizableStruct {
jobject window;
jboolean resizable;
};
// struct for _UpdateInsets() method
struct UpdateInsetsStruct {
jobject window;
jobject insets;
};
// struct for _ReshapeFrame() method
struct ReshapeFrameStruct {
jobject frame;
jint x, y;
jint w, h;
};
// struct for _SetIconImagesData
struct SetIconImagesDataStruct {
jobject window;
jintArray iconRaster;
jint w, h;
jintArray smallIconRaster;
jint smw, smh;
};
// struct for _SetMinSize() method
// and other methods setting sizes
struct SizeStruct {
jobject window;
jint w, h;
};
// struct for _SetFocusableWindow() method
struct SetFocusableWindowStruct {
jobject window;
jboolean isFocusableWindow;
};
// struct for _ModalDisable() method
struct ModalDisableStruct {
jobject window;
jlong blockerHWnd;
};
// struct for _SetOpacity() method
struct OpacityStruct {
jobject window;
jint iOpacity;
};
// struct for _SetOpaque() method
struct OpaqueStruct {
jobject window;
jboolean isOpaque;
};
// struct for _UpdateWindow() method
struct UpdateWindowStruct {
jobject window;
jintArray data;
HBITMAP hBitmap;
jint width, height;
};
// Struct for _RequestWindowFocus() method
struct RequestWindowFocusStruct {
jobject component;
jboolean isMouseEventCause;
};
// struct for _RepositionSecurityWarning() method
struct RepositionSecurityWarningStruct {
jobject window;
};
struct SetFullScreenExclusiveModeStateStruct {
jobject window;
jboolean isFSEMState;
};
/************************************************************************
* AwtWindow fields
*/
jfieldID AwtWindow::warningStringID;
jfieldID AwtWindow::locationByPlatformID;
jfieldID AwtWindow::autoRequestFocusID;
jfieldID AwtWindow::securityWarningWidthID;
jfieldID AwtWindow::securityWarningHeightID;
jfieldID AwtWindow::sysXID;
jfieldID AwtWindow::sysYID;
jfieldID AwtWindow::sysWID;
jfieldID AwtWindow::sysHID;
jfieldID AwtWindow::windowTypeID;
jmethodID AwtWindow::getWarningStringMID;
jmethodID AwtWindow::calculateSecurityWarningPositionMID;
jmethodID AwtWindow::windowTypeNameMID;
int AwtWindow::ms_instanceCounter = 0;
HHOOK AwtWindow::ms_hCBTFilter;
AwtWindow * AwtWindow::m_grabbedWindow = NULL;
BOOL AwtWindow::sm_resizing = FALSE;
UINT AwtWindow::untrustedWindowsCounter = 0;
/************************************************************************
* AwtWindow class methods
*/
AwtWindow::AwtWindow() {
m_sizePt.x = m_sizePt.y = 0;
m_owningFrameDialog = NULL;
m_isResizable = FALSE;//Default value is replaced after construction
m_minSize.x = m_minSize.y = 0;
m_hIcon = NULL;
m_hIconSm = NULL;
m_iconInherited = FALSE;
VERIFY(::SetRectEmpty(&m_insets));
VERIFY(::SetRectEmpty(&m_old_insets));
VERIFY(::SetRectEmpty(&m_warningRect));
// what's the best initial value?
m_screenNum = -1;
ms_instanceCounter++;
m_grabbed = FALSE;
m_isFocusableWindow = TRUE;
m_isRetainingHierarchyZOrder = FALSE;
m_filterFocusAndActivation = FALSE;
if (AwtWindow::ms_instanceCounter == 1) {
AwtWindow::ms_hCBTFilter =
::SetWindowsHookEx(WH_CBT, (HOOKPROC)AwtWindow::CBTFilter,
0, AwtToolkit::MainThread());
}
m_opaque = TRUE;
m_opacity = 0xff;
warningString = NULL;
warningWindow = NULL;
securityTooltipWindow = NULL;
securityWarningAnimationStage = 0;
currentWmSizeState = SIZE_RESTORED;
hContentBitmap = NULL;
::InitializeCriticalSection(&contentBitmapCS);
m_windowType = NORMAL;
m_alwaysOnTop = false;
fullScreenExclusiveModeState = FALSE;
}
AwtWindow::~AwtWindow()
{
if (warningString != NULL) {
delete [] warningString;
}
DeleteContentBitmap();
::DeleteCriticalSection(&contentBitmapCS);
}
void AwtWindow::Dispose()
{
// Fix 4745575 GDI Resource Leak
// MSDN
// Before a window is destroyed (that is, before it returns from processing
// the WM_NCDESTROY message), an application must remove all entries it has
// added to the property list. The application must use the RemoveProp function
// to remove the entries.
if (--AwtWindow::ms_instanceCounter == 0) {
::UnhookWindowsHookEx(AwtWindow::ms_hCBTFilter);
}
::RemoveProp(GetHWnd(), ModalBlockerProp);
if (m_grabbedWindow == this) {
Ungrab();
}
if ((m_hIcon != NULL) && !m_iconInherited) {
::DestroyIcon(m_hIcon);
}
if ((m_hIconSm != NULL) && !m_iconInherited) {
::DestroyIcon(m_hIconSm);
}
AwtCanvas::Dispose();
}
void
AwtWindow::Grab() {
JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
if (m_grabbedWindow != NULL) {
m_grabbedWindow->Ungrab();
}
m_grabbed = TRUE;
m_grabbedWindow = this;
if (AwtComponent::GetFocusedWindow() == NULL && IsFocusableWindow()) {
// we shouldn't perform grab in this case (see 4841881 & 6539458)
Ungrab();
} else if (GetHWnd() != AwtComponent::GetFocusedWindow()) {
_ToFront(env->NewGlobalRef(GetPeer(env)));
// Global ref was deleted in _ToFront
}
}
void
AwtWindow::Ungrab(BOOL doPost) {
if (m_grabbed && m_grabbedWindow == this) {
if (doPost) {
PostUngrabEvent();
}
m_grabbedWindow = NULL;
m_grabbed = FALSE;
}
}
void
AwtWindow::Ungrab() {
Ungrab(TRUE);
}
void AwtWindow::_Grab(void * param) {
JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
jobject self = (jobject)param;
if (env->EnsureLocalCapacity(1) < 0)
{
env->DeleteGlobalRef(self);
return;
}
AwtWindow *p = NULL;
PDATA pData;
JNI_CHECK_PEER_GOTO(self, ret);
p = (AwtWindow *)pData;
p->Grab();
ret:
env->DeleteGlobalRef(self);
}
void AwtWindow::_Ungrab(void * param) {
JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
jobject self = (jobject)param;
if (env->EnsureLocalCapacity(1) < 0)
{
env->DeleteGlobalRef(self);
return;
}
AwtWindow *p = NULL;
PDATA pData;
JNI_CHECK_PEER_GOTO(self, ret);
p = (AwtWindow *)pData;
p->Ungrab(FALSE);
ret:
env->DeleteGlobalRef(self);
}
MsgRouting AwtWindow::WmNcMouseDown(WPARAM hitTest, int x, int y, int button) {
if (m_grabbedWindow != NULL && !m_grabbedWindow->IsOneOfOwnersOf(this)) {
m_grabbedWindow->Ungrab();
}
return AwtCanvas::WmNcMouseDown(hitTest, x, y, button);
}
MsgRouting AwtWindow::WmWindowPosChanging(LPARAM windowPos) {
return mrDoDefault;
}
void AwtWindow::RepositionSecurityWarning(JNIEnv *env)
{
RECT rect;
CalculateWarningWindowBounds(env, &rect);
::SetWindowPos(warningWindow, IsAlwaysOnTop() ? HWND_TOPMOST : HWND_NOTOPMOST,
rect.left, rect.top,
rect.right - rect.left, rect.bottom - rect.top,
SWP_ASYNCWINDOWPOS | SWP_NOACTIVATE |
SWP_NOOWNERZORDER
);
}
MsgRouting AwtWindow::WmWindowPosChanged(LPARAM windowPos) {
WINDOWPOS * wp = (WINDOWPOS *)windowPos;
// Reposition the warning window
if (IsUntrusted() && warningWindow != NULL) {
if (wp->flags & SWP_HIDEWINDOW) {
UpdateSecurityWarningVisibility();
}
RepositionSecurityWarning((JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2));
if (wp->flags & SWP_SHOWWINDOW) {
UpdateSecurityWarningVisibility();
}
}
if (wp->flags & SWP_HIDEWINDOW) {
EnableTranslucency(FALSE);
}
return mrDoDefault;
}
LPCTSTR AwtWindow::GetClassName() {
return TEXT("SunAwtWindow");
}
void AwtWindow::FillClassInfo(WNDCLASSEX *lpwc)
{
AwtComponent::FillClassInfo(lpwc);
/*
* This line causes bug #4189244 (Swing Popup menu is not being refreshed (cleared) under a Dialog)
* so it's comment out (son@sparc.spb.su)
*
* lpwc->style |= CS_SAVEBITS; // improve pull-down menu performance
*/
lpwc->cbWndExtra = DLGWINDOWEXTRA;
}
bool AwtWindow::IsWarningWindow(HWND hWnd)
{
const UINT len = 128;
TCHAR windowClassName[len];
::RealGetWindowClass(hWnd, windowClassName, len);
return 0 == _tcsncmp(windowClassName,
AwtWindow::GetWarningWindowClassName(), len);
}
LRESULT CALLBACK AwtWindow::CBTFilter(int nCode, WPARAM wParam, LPARAM lParam)
{
if (nCode == HCBT_ACTIVATE || nCode == HCBT_SETFOCUS) {
HWND hWnd = (HWND)wParam;
AwtComponent *comp = AwtComponent::GetComponent(hWnd);
if (comp == NULL) {
// Check if it's a security warning icon
// See: 5091224, 6181725, 6732583
if (AwtWindow::IsWarningWindow(hWnd)) {
return 1;
}
} else {
if (comp->IsTopLevel()) {
AwtWindow* win = (AwtWindow*)comp;
if (!win->IsFocusableWindow() ||
win->m_filterFocusAndActivation)
{
return 1; // Don't change focus/activation.
}
}
}
}
return ::CallNextHookEx(AwtWindow::ms_hCBTFilter, nCode, wParam, lParam);
}
void AwtWindow::InitSecurityWarningSize(JNIEnv *env)
{
warningWindowWidth = ::GetSystemMetrics(SM_CXSMICON);
warningWindowHeight = ::GetSystemMetrics(SM_CYSMICON);
jobject target = GetTarget(env);
env->SetIntField(target, AwtWindow::securityWarningWidthID,
warningWindowWidth);
env->SetIntField(target, AwtWindow::securityWarningHeightID,
warningWindowHeight);
env->DeleteLocalRef(target);
}
void AwtWindow::CreateHWnd(JNIEnv *env, LPCWSTR title,
DWORD windowStyle,
DWORD windowExStyle,
int x, int y, int w, int h,
HWND hWndParent, HMENU hMenu,
COLORREF colorForeground,
COLORREF colorBackground,
jobject peer)
{
// Retrieve the warning string
// Note: we need to get it before CreateHWnd() happens because
// the isUntrusted() method may be invoked while the HWND
// is being created in response to some window messages.
jobject target = env->GetObjectField(peer, AwtObject::targetID);
jstring javaWarningString =
(jstring)env->CallObjectMethod(target, AwtWindow::getWarningStringMID);
if (javaWarningString != NULL) {
size_t length = env->GetStringLength(javaWarningString) + 1;
warningString = new WCHAR[length];
env->GetStringRegion(javaWarningString, 0,
static_cast<jsize>(length - 1), reinterpret_cast(warningString));
warningString[length-1] = L'\0';
env->DeleteLocalRef(javaWarningString);
}
env->DeleteLocalRef(target);
InitType(env, peer);
TweakStyle(windowStyle, windowExStyle);
AwtCanvas::CreateHWnd(env, title,
windowStyle,
windowExStyle,
x, y, w, h,
hWndParent, hMenu,
colorForeground,
colorBackground,
peer);
// Now we need to create the warning window.
CreateWarningWindow(env);
}
void AwtWindow::CreateWarningWindow(JNIEnv *env)
{
if (!IsUntrusted()) {
return;
}
if (++AwtWindow::untrustedWindowsCounter == 1) {
AwtToolkit::GetInstance().InstallMouseLowLevelHook();
}
InitSecurityWarningSize(env);
RECT rect;
CalculateWarningWindowBounds(env, &rect);
RegisterWarningWindowClass();
warningWindow = ::CreateWindowEx(
WS_EX_NOACTIVATE,
GetWarningWindowClassName(),
warningString,
WS_POPUP,
rect.left, rect.top,
rect.right - rect.left, rect.bottom - rect.top,
GetHWnd(), // owner
NULL, // menu
AwtToolkit::GetInstance().GetModuleHandle(),
NULL // lParam
);
if (warningWindow == NULL) {
//XXX: actually this is bad... We didn't manage to create the window.
return;
}
HICON hIcon = GetSecurityWarningIcon();
ICONINFO ii;
::GetIconInfo(hIcon, &ii);
//Note: we assume that every security icon has exactly the same shape.
HRGN rgn = BitmapUtil::BitmapToRgn(ii.hbmColor);
if (rgn) {
::SetWindowRgn(warningWindow, rgn, TRUE);
}
// Now we need to create the tooltip control for this window.
if (!ComCtl32Util::GetInstance().IsToolTipControlInitialized()) {
return;
}
securityTooltipWindow = ::CreateWindowEx(
WS_EX_TOPMOST,
TOOLTIPS_CLASS,
NULL,
WS_POPUP | TTS_NOPREFIX | TTS_ALWAYSTIP,
CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
warningWindow,
NULL,
AwtToolkit::GetInstance().GetModuleHandle(),
NULL
);
::SetWindowPos(securityTooltipWindow,
HWND_TOPMOST, 0, 0, 0, 0,
SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE);
// We currently don't expect changing the size of the window,
// hence we may not care of updating the TOOL position/size.
::GetClientRect(warningWindow, &rect);
TOOLINFO ti;
ti.cbSize = sizeof(ti);
ti.uFlags = TTF_SUBCLASS;
ti.hwnd = warningWindow;
ti.hinst = AwtToolkit::GetInstance().GetModuleHandle();
ti.uId = 0;
ti.lpszText = warningString;
ti.rect.left = rect.left;
ti.rect.top = rect.top;
ti.rect.right = rect.right;
ti.rect.bottom = rect.bottom;
::SendMessage(securityTooltipWindow, TTM_ADDTOOL,
0, (LPARAM) (LPTOOLINFO) &ti);
}
void AwtWindow::DestroyWarningWindow()
{
if (!IsUntrusted()) {
return;
}
if (--AwtWindow::untrustedWindowsCounter == 0) {
AwtToolkit::GetInstance().UninstallMouseLowLevelHook();
}
if (warningWindow != NULL) {
// Note that the warningWindow is an owned window, and hence
// it would be destroyed automatically. However, the window
// class may only be unregistered if there's no any single
// window left using this class. Thus, we're destroying the
// warning window manually. Note that the tooltip window
// will be destroyed automatically because it's an owned
// window as well.
::DestroyWindow(warningWindow);
warningWindow = NULL;
securityTooltipWindow = NULL;
UnregisterWarningWindowClass();
}
}
void AwtWindow::DestroyHWnd()
{
DestroyWarningWindow();
AwtCanvas::DestroyHWnd();
}
LPCTSTR AwtWindow::GetWarningWindowClassName()
{
return TEXT("SunAwtWarningWindow");
}
void AwtWindow::FillWarningWindowClassInfo(WNDCLASS *lpwc)
{
lpwc->style = 0L;
lpwc->lpfnWndProc = (WNDPROC)WarningWindowProc;
lpwc->cbClsExtra = 0;
lpwc->cbWndExtra = 0;
lpwc->hInstance = AwtToolkit::GetInstance().GetModuleHandle(),
lpwc->hIcon = AwtToolkit::GetInstance().GetAwtIcon();
lpwc->hCursor = ::LoadCursor(NULL, IDC_ARROW);
lpwc->hbrBackground = NULL;
lpwc->lpszMenuName = NULL;
lpwc->lpszClassName = AwtWindow::GetWarningWindowClassName();
}
void AwtWindow::RegisterWarningWindowClass()
{
WNDCLASS wc;
::ZeroMemory(&wc, sizeof(wc));
if (!::GetClassInfo(AwtToolkit::GetInstance().GetModuleHandle(),
AwtWindow::GetWarningWindowClassName(), &wc))
{
AwtWindow::FillWarningWindowClassInfo(&wc);
ATOM atom = ::RegisterClass(&wc);
DASSERT(atom != 0);
}
}
void AwtWindow::UnregisterWarningWindowClass()
{
::UnregisterClass(AwtWindow::GetWarningWindowClassName(), AwtToolkit::GetInstance().GetModuleHandle());
}
HICON AwtWindow::GetSecurityWarningIcon()
{
// It is assumed that the icon at index 0 is gray
const UINT index = securityAnimationKind == akShow ?
securityWarningAnimationStage : 0;
HICON ico = AwtToolkit::GetInstance().GetSecurityWarningIcon(index,
warningWindowWidth, warningWindowHeight);
return ico;
}
// This function calculates the bounds of the warning window and stores them
// into the RECT structure pointed by the argument rect.
void AwtWindow::CalculateWarningWindowBounds(JNIEnv *env, LPRECT rect)
{
RECT windowBounds;
AwtToolkit::GetWindowRect(GetHWnd(), &windowBounds);
jobject target = GetTarget(env);
jobject point2D = env->CallObjectMethod(target,
calculateSecurityWarningPositionMID,
(jdouble)windowBounds.left, (jdouble)windowBounds.top,
(jdouble)(windowBounds.right - windowBounds.left),
(jdouble)(windowBounds.bottom - windowBounds.top));
env->DeleteLocalRef(target);
static jclass point2DClassID = NULL;
static jmethodID point2DGetXMID = NULL;
static jmethodID point2DGetYMID = NULL;
if (point2DClassID == NULL) {
jclass point2DClassIDLocal = env->FindClass("java/awt/geom/Point2D");
point2DClassID = (jclass)env->NewGlobalRef(point2DClassIDLocal);
env->DeleteLocalRef(point2DClassIDLocal);
}
if (point2DGetXMID == NULL) {
point2DGetXMID = env->GetMethodID(point2DClassID, "getX", "()D");
}
if (point2DGetYMID == NULL) {
point2DGetYMID = env->GetMethodID(point2DClassID, "getY", "()D");
}
int x = (int)env->CallDoubleMethod(point2D, point2DGetXMID);
int y = (int)env->CallDoubleMethod(point2D, point2DGetYMID);
env->DeleteLocalRef(point2D);
rect->left = x;
rect->top = y;
rect->right = rect->left + warningWindowWidth;
rect->bottom = rect->top + warningWindowHeight;
}
LRESULT CALLBACK AwtWindow::WarningWindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
switch (uMsg) {
case WM_PAINT:
PaintWarningWindow(hwnd);
return 0;
case WM_MOUSEACTIVATE:
{
// Retrive the owner of the warning window.
HWND javaWindow = ::GetParent(hwnd);
if (javaWindow) {
// If the window is blocked by a modal dialog, substitute
// its handle with the topmost blocker.
HWND topmostBlocker = GetTopmostModalBlocker(javaWindow);
if (::IsWindow(topmostBlocker)) {
javaWindow = topmostBlocker;
}
::BringWindowToTop(javaWindow);
AwtWindow * window =
(AwtWindow*)AwtComponent::GetComponent(javaWindow);
if (window == NULL) {
// Quite unlikely to go into here, but it's way better
// than getting a crash.
::SetForegroundWindow(javaWindow);
} else {
// Activate the window if it is focusable and inactive
if (window->IsFocusableWindow() &&
javaWindow != ::GetActiveWindow()) {
::SetForegroundWindow(javaWindow);
} else {
// ...otherwise just start the animation.
window->StartSecurityAnimation(akShow);
}
}
// In every case if there's a top-most blocker, we need to
// enable modal animation.
if (::IsWindow(topmostBlocker)) {
AwtDialog::AnimateModalBlocker(topmostBlocker);
}
}
return MA_NOACTIVATEANDEAT;
}
}
return ::DefWindowProc(hwnd, uMsg, wParam, lParam);
}
void AwtWindow::PaintWarningWindow(HWND warningWindow)
{
RECT updateRect;
if (!::GetUpdateRect(warningWindow, &updateRect, FALSE)) {
// got nothing to update
return;
}
PAINTSTRUCT ps;
HDC hdc = ::BeginPaint(warningWindow, &ps);
if (hdc == NULL) {
// indicates an error
return;
}
PaintWarningWindow(warningWindow, hdc);
::EndPaint(warningWindow, &ps);
}
void AwtWindow::PaintWarningWindow(HWND warningWindow, HDC hdc)
{
HWND javaWindow = ::GetParent(warningWindow);
AwtWindow * window = (AwtWindow*)AwtComponent::GetComponent(javaWindow);
if (window == NULL) {
return;
}
::DrawIconEx(hdc, 0, 0, window->GetSecurityWarningIcon(),
window->warningWindowWidth, window->warningWindowHeight,
0, NULL, DI_NORMAL);
}
static const UINT_PTR IDT_AWT_SECURITYANIMATION = 0x102;
// Approximately 6 times a second. 0.75 seconds total.
static const UINT securityAnimationTimerElapse = 150;
static const UINT securityAnimationMaxIterations = 5;
void AwtWindow::RepaintWarningWindow()
{
HDC hdc = ::GetDC(warningWindow);
PaintWarningWindow(warningWindow, hdc);
::ReleaseDC(warningWindow, hdc);
}
void AwtWindow::SetLayered(HWND window, bool layered)
{
const LONG ex_style = ::GetWindowLong(window, GWL_EXSTYLE);
::SetWindowLong(window, GWL_EXSTYLE, layered ?
ex_style | WS_EX_LAYERED : ex_style & ~WS_EX_LAYERED);
}
bool AwtWindow::IsLayered(HWND window)
{
const LONG ex_style = ::GetWindowLong(window, GWL_EXSTYLE);
return ex_style & WS_EX_LAYERED;
}
void AwtWindow::StartSecurityAnimation(AnimationKind kind)
{
if (!IsUntrusted()) {
return;
}
if (warningWindow == NULL) {
return;
}
securityAnimationKind = kind;
securityWarningAnimationStage = 1;
::SetTimer(GetHWnd(), IDT_AWT_SECURITYANIMATION,
securityAnimationTimerElapse, NULL);
if (securityAnimationKind == akShow) {
::SetWindowPos(warningWindow,
IsAlwaysOnTop() ? HWND_TOPMOST : HWND_NOTOPMOST,
0, 0, 0, 0,
SWP_NOACTIVATE | SWP_NOSIZE | SWP_NOMOVE |
SWP_SHOWWINDOW | SWP_NOOWNERZORDER);
::SetLayeredWindowAttributes(warningWindow, RGB(0, 0, 0),
0xFF, LWA_ALPHA);
AwtWindow::SetLayered(warningWindow, false);
::RedrawWindow(warningWindow, NULL, NULL,
RDW_ERASE | RDW_INVALIDATE | RDW_FRAME | RDW_ALLCHILDREN);
} else if (securityAnimationKind == akPreHide) {
// Pre-hiding means fading-out. We have to make the window layered.
// Note: Some VNC clients do not support layered windows, hence
// we dynamically turn it on and off. See 6805231.
AwtWindow::SetLayered(warningWindow, true);
}
}
void AwtWindow::StopSecurityAnimation()
{
if (!IsUntrusted()) {
return;
}
if (warningWindow == NULL) {
return;
}
securityWarningAnimationStage = 0;
::KillTimer(GetHWnd(), IDT_AWT_SECURITYANIMATION);
switch (securityAnimationKind) {
case akHide:
case akPreHide:
::SetWindowPos(warningWindow, HWND_NOTOPMOST, 0, 0, 0, 0,
SWP_NOACTIVATE | SWP_NOSIZE | SWP_NOMOVE |
SWP_HIDEWINDOW | SWP_NOOWNERZORDER);
break;
case akShow:
RepaintWarningWindow();
break;
}
securityAnimationKind = akNone;
}
MsgRouting AwtWindow::WmTimer(UINT_PTR timerID)
{
if (timerID != IDT_AWT_SECURITYANIMATION) {
return mrPassAlong;
}
if (securityWarningAnimationStage == 0) {
return mrConsume;
}
securityWarningAnimationStage++;
if (securityWarningAnimationStage >= securityAnimationMaxIterations) {
if (securityAnimationKind == akPreHide) {
// chain real hiding
StartSecurityAnimation(akHide);
} else {
StopSecurityAnimation();
}
} else {
switch (securityAnimationKind) {
case akHide:
{
BYTE opacity = ((int)0xFF *
(securityAnimationMaxIterations -
securityWarningAnimationStage)) /
securityAnimationMaxIterations;
::SetLayeredWindowAttributes(warningWindow,
RGB(0, 0, 0), opacity, LWA_ALPHA);
}
break;
case akShow:
case akNone: // quite unlikely, but quite safe
RepaintWarningWindow();
break;
}
}
return mrConsume;
}
// The security warning is visible if:
// 1. The window has the keyboard window focus, OR
// 2. The mouse pointer is located within the window bounds,
// or within the security warning icon.
void AwtWindow::UpdateSecurityWarningVisibility()
{
if (!IsUntrusted()) {
return;
}
if (warningWindow == NULL) {
return;
}
bool show = false;
if (IsVisible() && currentWmSizeState != SIZE_MINIMIZED &&
!isFullScreenExclusiveMode())
{
if (AwtComponent::GetFocusedWindow() == GetHWnd()) {
show = true;
}
HWND hwnd = AwtToolkit::GetInstance().GetWindowUnderMouse();
if (hwnd == GetHWnd()) {
show = true;
}
if (hwnd == warningWindow) {
show = true;
}
}
if (show && (!::IsWindowVisible(warningWindow) ||
securityAnimationKind == akHide ||
securityAnimationKind == akPreHide)) {
StartSecurityAnimation(akShow);
}
if (!show && ::IsWindowVisible(warningWindow)) {
StartSecurityAnimation(akPreHide);
}
}
void AwtWindow::FocusedWindowChanged(HWND from, HWND to)
{
AwtWindow * fw = (AwtWindow *)AwtComponent::GetComponent(from);
AwtWindow * tw = (AwtWindow *)AwtComponent::GetComponent(to);
if (fw != NULL) {
fw->UpdateSecurityWarningVisibility();
}
if (tw != NULL) {
tw->UpdateSecurityWarningVisibility();
// Flash on receiving the keyboard focus even if the warning
// has already been shown (e.g. by hovering with the mouse)
tw->StartSecurityAnimation(akShow);
}
}
void AwtWindow::_RepositionSecurityWarning(void* param)
{
JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
RepositionSecurityWarningStruct *rsws =
(RepositionSecurityWarningStruct *)param;
jobject self = rsws->window;
PDATA pData;
JNI_CHECK_PEER_GOTO(self, ret);
AwtWindow *window = (AwtWindow *)pData;
window->RepositionSecurityWarning(env);
ret:
env->DeleteGlobalRef(self);
delete rsws;
}
void AwtWindow::InitType(JNIEnv *env, jobject peer)
{
jobject type = env->GetObjectField(peer, windowTypeID);
if (type == NULL) {
return;
}
jstring value = (jstring)env->CallObjectMethod(type, windowTypeNameMID);
if (value == NULL) {
env->DeleteLocalRef(type);
return;
}
const char* valueNative = env->GetStringUTFChars(value, 0);
if (valueNative == NULL) {
env->DeleteLocalRef(value);
env->DeleteLocalRef(type);
return;
}
if (strcmp(valueNative, "UTILITY") == 0) {
m_windowType = UTILITY;
} else if (strcmp(valueNative, "POPUP") == 0) {
m_windowType = POPUP;
}
env->ReleaseStringUTFChars(value, valueNative);
env->DeleteLocalRef(value);
env->DeleteLocalRef(type);
}
void AwtWindow::TweakStyle(DWORD & style, DWORD & exStyle)
{
switch (GetType()) {
case UTILITY:
exStyle |= WS_EX_TOOLWINDOW;
break;
case POPUP:
style &= ~WS_OVERLAPPED;
style |= WS_POPUP;
break;
}
}
/* Create a new AwtWindow object and window. */
AwtWindow* AwtWindow::Create(jobject self, jobject parent)
{
JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
jobject target = NULL;
AwtWindow* window = NULL;
try {
if (env->EnsureLocalCapacity(1) < 0) {
return NULL;
}
AwtWindow* awtParent = NULL;
PDATA pData;
if (parent != NULL) {
JNI_CHECK_PEER_GOTO(parent, done);
awtParent = (AwtWindow *)pData;
}
target = env->GetObjectField(self, AwtObject::targetID);
JNI_CHECK_NULL_GOTO(target, "null target", done);
window = new AwtWindow();
{
if (JNU_IsInstanceOfByName(env, target, "javax/swing/Popup$HeavyWeightWindow") > 0) {
window->m_isRetainingHierarchyZOrder = TRUE;
}
DWORD style = WS_CLIPCHILDREN | WS_POPUP;
DWORD exStyle = WS_EX_NOACTIVATE;
if (GetRTL()) {
exStyle |= WS_EX_RIGHT | WS_EX_LEFTSCROLLBAR;
if (GetRTLReadingOrder())
exStyle |= WS_EX_RTLREADING;
}
if (awtParent != NULL) {
window->InitOwner(awtParent);
} else {
// specify WS_EX_TOOLWINDOW to remove parentless windows from taskbar
exStyle |= WS_EX_TOOLWINDOW;
}
window->CreateHWnd(env, L"",
style, exStyle,
0, 0, 0, 0,
(awtParent != NULL) ? awtParent->GetHWnd() : NULL,
NULL,
::GetSysColor(COLOR_WINDOWTEXT),
::GetSysColor(COLOR_WINDOW),
self);
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);
/*
* Initialize icon as inherited from parent if it exists
*/
if (parent != NULL) {
window->m_hIcon = awtParent->GetHIcon();
window->m_hIconSm = awtParent->GetHIconSm();
window->m_iconInherited = TRUE;
}
window->DoUpdateIcon();
/*
* Reshape here instead of during create, so that a WM_NCCALCSIZE
* is sent.
*/
window->Reshape(x, y, width, height);
}
} catch (...) {
env->DeleteLocalRef(target);
throw;
}
done:
env->DeleteLocalRef(target);
return window;
}
BOOL AwtWindow::IsOneOfOwnersOf(AwtWindow * wnd) {
while (wnd != NULL) {
if (wnd == this || wnd->GetOwningFrameOrDialog() == this) return TRUE;
wnd = (AwtWindow*)GetComponent(::GetWindow(wnd->GetHWnd(), GW_OWNER));
}
return FALSE;
}
void AwtWindow::InitOwner(AwtWindow *owner)
{
DASSERT(owner != NULL);
while (owner != NULL && owner->IsSimpleWindow()) {
HWND ownerOwnerHWND = ::GetWindow(owner->GetHWnd(), GW_OWNER);
if (ownerOwnerHWND == NULL) {
owner = NULL;
break;
}
owner = (AwtWindow *)AwtComponent::GetComponent(ownerOwnerHWND);
}
m_owningFrameDialog = (AwtFrame *)owner;
}
void AwtWindow::moveToDefaultLocation() {
HWND boggy = ::CreateWindow(GetClassName(), L"BOGGY", WS_OVERLAPPED, CW_USEDEFAULT, 0 ,0, 0,
NULL, NULL, NULL, NULL);
RECT defLoc;
// Fixed 6477497: Windows drawn off-screen on Win98, even when java.awt.Window.locationByPlatform is set
// Win9x does not position a window until the window is shown.
// The behavior is slightly opposite to the WinNT (and up), where
// Windows will position the window upon creation of the window.
// That's why we have to manually set the left & top values of
// the defLoc to 0 if the GetWindowRect function returns FALSE.
BOOL result = ::GetWindowRect(boggy, &defLoc);
if (!result) {
defLoc.left = defLoc.top = 0;
}
VERIFY(::DestroyWindow(boggy));
VERIFY(::SetWindowPos(GetHWnd(), NULL, defLoc.left, defLoc.top, 0, 0, SWP_NOSIZE | SWP_NOZORDER));
}
void AwtWindow::Show()
{
m_visible = true;
JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
BOOL done = false;
HWND hWnd = GetHWnd();
if (env->EnsureLocalCapacity(2) < 0) {
return;
}
jobject target = GetTarget(env);
INT nCmdShow;
AwtFrame* owningFrame = GetOwningFrameOrDialog();
if (IsFocusableWindow() && IsAutoRequestFocus() && owningFrame != NULL &&
::GetForegroundWindow() == owningFrame->GetHWnd())
{
nCmdShow = SW_SHOW;
} else {
nCmdShow = SW_SHOWNA;
}
BOOL locationByPlatform = env->GetBooleanField(GetTarget(env), AwtWindow::locationByPlatformID);
if (locationByPlatform) {
moveToDefaultLocation();
}
EnableTranslucency(TRUE);
// The following block exists to support Menu/Tooltip animation for
// Swing programs in a way which avoids introducing any new public api into
// AWT or Swing.
// This code should eventually be replaced by a better longterm solution
// which might involve tagging java.awt.Window instances with a semantic
// property so platforms can animate/decorate/etc accordingly.
//
if (JNU_IsInstanceOfByName(env, target, "com/sun/java/swing/plaf/windows/WindowsPopupWindow") > 0)
{
// need this global ref to make the class unloadable (see 6500204)
static jclass windowsPopupWindowCls;
static jfieldID windowTypeFID = NULL;
jint windowType = 0;
BOOL animateflag = FALSE;
BOOL fadeflag = FALSE;
DWORD animateStyle = 0;
if (windowTypeFID == NULL) {
// Initialize Window type constants ONCE...
jfieldID windowTYPESFID[TYPES_COUNT];
jclass cls = env->GetObjectClass(target);
windowTypeFID = env->GetFieldID(cls, "windowType", "I");
windowTYPESFID[UNSPECIFIED] = env->GetStaticFieldID(cls, "UNDEFINED_WINDOW_TYPE", "I");
windowTYPESFID[TOOLTIP] = env->GetStaticFieldID(cls, "TOOLTIP_WINDOW_TYPE", "I");
windowTYPESFID[MENU] = env->GetStaticFieldID(cls, "MENU_WINDOW_TYPE", "I");
windowTYPESFID[SUBMENU] = env->GetStaticFieldID(cls, "SUBMENU_WINDOW_TYPE", "I");
windowTYPESFID[POPUPMENU] = env->GetStaticFieldID(cls, "POPUPMENU_WINDOW_TYPE", "I");
windowTYPESFID[COMBOBOX_POPUP] = env->GetStaticFieldID(cls, "COMBOBOX_POPUP_WINDOW_TYPE", "I");
for (int i=0; i < 6; i++) {
windowTYPES[i] = env->GetStaticIntField(cls, windowTYPESFID[i]);
}
windowsPopupWindowCls = (jclass) env->NewGlobalRef(cls);
env->DeleteLocalRef(cls);
}
windowType = env->GetIntField(target, windowTypeFID);
if (windowType == windowTYPES[TOOLTIP]) {
SystemParametersInfo(SPI_GETTOOLTIPANIMATION, 0, &animateflag, 0);
SystemParametersInfo(SPI_GETTOOLTIPFADE, 0, &fadeflag, 0);
if (animateflag) {
// AW_BLEND currently produces runtime parameter error
// animateStyle = fadeflag? AW_BLEND : AW_SLIDE | AW_VER_POSITIVE;
animateStyle = fadeflag? 0 : AW_SLIDE | AW_VER_POSITIVE;
}
} else if (windowType == windowTYPES[MENU] || windowType == windowTYPES[SUBMENU] ||
windowType == windowTYPES[POPUPMENU]) {
SystemParametersInfo(SPI_GETMENUANIMATION, 0, &animateflag, 0);
if (animateflag) {
SystemParametersInfo(SPI_GETMENUFADE, 0, &fadeflag, 0);
if (fadeflag) {
// AW_BLEND currently produces runtime parameter error
//animateStyle = AW_BLEND;
}
if (animateStyle == 0 && !fadeflag) {
animateStyle = AW_SLIDE;
if (windowType == windowTYPES[MENU]) {
animateStyle |= AW_VER_POSITIVE;
} else if (windowType == windowTYPES[SUBMENU]) {
animateStyle |= AW_HOR_POSITIVE;
} else { /* POPUPMENU */
animateStyle |= (AW_VER_POSITIVE | AW_HOR_POSITIVE);
}
}
}
} else if (windowType == windowTYPES[COMBOBOX_POPUP]) {
SystemParametersInfo(SPI_GETCOMBOBOXANIMATION, 0, &animateflag, 0);
if (animateflag) {
animateStyle = AW_SLIDE | AW_VER_POSITIVE;
}
}
if (animateStyle != 0) {
BOOL result = ::AnimateWindow(hWnd, (DWORD)200, animateStyle);
if (!result) {
// TODO: log message
} else {
// WM_PAINT is not automatically sent when invoking AnimateWindow,
// so force an expose event
RECT rect;
::GetWindowRect(hWnd,&rect);
::ScreenToClient(hWnd, (LPPOINT)&rect);
::InvalidateRect(hWnd, &rect, TRUE);
::UpdateWindow(hWnd);
done = TRUE;
}
}
}
if (!done) {
// transient windows shouldn't change the owner window's position in the z-order
if (IsRetainingHierarchyZOrder()){
UINT flags = SWP_NOSIZE | SWP_NOMOVE | SWP_SHOWWINDOW | SWP_NOOWNERZORDER;
if (nCmdShow == SW_SHOWNA) {
flags |= SWP_NOACTIVATE;
}
::SetWindowPos(GetHWnd(), HWND_TOPMOST, 0, 0, 0, 0, flags);
} else {
::ShowWindow(GetHWnd(), nCmdShow);
}
}
env->DeleteLocalRef(target);
}
/*
* Get and return the insets for this window (container, really).
* Calculate & cache them while we're at it, for use by AwtGraphics
*/
BOOL AwtWindow::UpdateInsets(jobject insets)
{
JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
DASSERT(GetPeer(env) != NULL);
if (env->EnsureLocalCapacity(2) < 0) {
return FALSE;
}
// fix 4167248 : don't update insets when frame is iconified
// to avoid bizarre window/client rectangles
if (::IsIconic(GetHWnd())) {
return FALSE;
}
/*
* Code to calculate insets. Stores results in frame's data
* members, and in the peer's Inset object.
*/
RECT outside;
RECT inside;
int extraBottomInsets = 0;
::GetClientRect(GetHWnd(), &inside);
::GetWindowRect(GetHWnd(), &outside);
/* Update our inset member */
if (outside.right - outside.left > 0 && outside.bottom - outside.top > 0) {
::MapWindowPoints(GetHWnd(), 0, (LPPOINT)&inside, 2);
m_insets.top = inside.top - outside.top;
m_insets.bottom = outside.bottom - inside.bottom + extraBottomInsets;
m_insets.left = inside.left - outside.left;
m_insets.right = outside.right - inside.right;
} else {
m_insets.top = -1;
}
if (m_insets.left < 0 || m_insets.top < 0 ||
m_insets.right < 0 || m_insets.bottom < 0)
{
/* This window hasn't been sized yet -- use system metrics. */
jobject target = GetTarget(env);
if (IsUndecorated() == FALSE) {
/* Get outer frame sizes. */
LONG style = GetStyle();
if (style & WS_THICKFRAME) {
m_insets.left = m_insets.right =
::GetSystemMetrics(SM_CXSIZEFRAME);
m_insets.top = m_insets.bottom =
::GetSystemMetrics(SM_CYSIZEFRAME);
} else {
m_insets.left = m_insets.right =
::GetSystemMetrics(SM_CXDLGFRAME);
m_insets.top = m_insets.bottom =
::GetSystemMetrics(SM_CYDLGFRAME);
}
/* Add in title. */
m_insets.top += ::GetSystemMetrics(SM_CYCAPTION);
}
else {
/* fix for 4418125: Undecorated frames are off by one */
/* undo the -1 set above */
/* Additional fix for 5059656 */
/* Also, 5089312: Window insets should be 0. */
::memset(&m_insets, 0, sizeof(m_insets));
}
/* Add in menuBar, if any. */
if (JNU_IsInstanceOfByName(env, target, "java/awt/Frame") > 0 &&
((AwtFrame*)this)->GetMenuBar()) {
m_insets.top += ::GetSystemMetrics(SM_CYMENU);
}
m_insets.bottom += extraBottomInsets;
env->DeleteLocalRef(target);
}
BOOL insetsChanged = FALSE;
jobject peer = GetPeer(env);
/* Get insets into our peer directly */
jobject peerInsets = (env)->GetObjectField(peer, AwtPanel::insets_ID);
DASSERT(!safe_ExceptionOccurred(env));
if (peerInsets != NULL) { // may have been called during creation
(env)->SetIntField(peerInsets, AwtInsets::topID, m_insets.top);
(env)->SetIntField(peerInsets, AwtInsets::bottomID,
m_insets.bottom);
(env)->SetIntField(peerInsets, AwtInsets::leftID, m_insets.left);
(env)->SetIntField(peerInsets, AwtInsets::rightID, m_insets.right);
}
/* Get insets into the Inset object (if any) that was passed */
if (insets != NULL) {
(env)->SetIntField(insets, AwtInsets::topID, m_insets.top);
(env)->SetIntField(insets, AwtInsets::bottomID, m_insets.bottom);
(env)->SetIntField(insets, AwtInsets::leftID, m_insets.left);
(env)->SetIntField(insets, AwtInsets::rightID, m_insets.right);
}
env->DeleteLocalRef(peerInsets);
insetsChanged = !::EqualRect( &m_old_insets, &m_insets );
::CopyRect( &m_old_insets, &m_insets );
if (insetsChanged) {
// Since insets are changed we need to update the surfaceData object
// to reflect that change
env->CallVoidMethod(peer, AwtComponent::replaceSurfaceDataLaterMID);
}
return insetsChanged;
}
/**
* Sometimes we need the hWnd that actually owns this Window's hWnd (if
* there is an owner).
*/
HWND AwtWindow::GetTopLevelHWnd()
{
return m_owningFrameDialog ? m_owningFrameDialog->GetHWnd() :
GetHWnd();
}
/*
* Although this function sends ComponentEvents, it needs to be defined
* here because only top-level windows need to have move and resize
* events fired from native code. All contained windows have these events
* fired from common Java code.
*/
void AwtWindow::SendComponentEvent(jint eventId)
{
JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
static jclass classEvent = NULL;
if (classEvent == NULL) {
if (env->PushLocalFrame(1) < 0)
return;
classEvent = env->FindClass("java/awt/event/ComponentEvent");
if (classEvent != NULL) {
classEvent = (jclass)env->NewGlobalRef(classEvent);
}
env->PopLocalFrame(0);
}
static jmethodID eventInitMID = NULL;
if (eventInitMID == NULL) {
eventInitMID = env->GetMethodID(classEvent, "<init>",
"(Ljava/awt/Component;I)V");
if (eventInitMID == NULL) {
return;
}
}
if (env->EnsureLocalCapacity(2) < 0) {
return;
}
jobject target = GetTarget(env);
jobject event = env->NewObject(classEvent, eventInitMID,
target, eventId);
DASSERT(!safe_ExceptionOccurred(env));
DASSERT(event != NULL);
SendEvent(event);
env->DeleteLocalRef(target);
env->DeleteLocalRef(event);
}
void AwtWindow::SendWindowEvent(jint id, HWND opposite,
jint oldState, jint newState)
{
JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
static jclass wClassEvent;
if (wClassEvent == NULL) {
if (env->PushLocalFrame(1) < 0)
return;
wClassEvent = env->FindClass("sun/awt/TimedWindowEvent");
if (wClassEvent != NULL) {
wClassEvent = (jclass)env->NewGlobalRef(wClassEvent);
}
env->PopLocalFrame(0);
if (wClassEvent == NULL) {
return;
}
}
static jmethodID wEventInitMID;
if (wEventInitMID == NULL) {
wEventInitMID =
env->GetMethodID(wClassEvent, "<init>",
"(Ljava/awt/Window;ILjava/awt/Window;IIJ)V");
DASSERT(wEventInitMID);
if (wEventInitMID == NULL) {
return;
}
}
static jclass sequencedEventCls;
if (sequencedEventCls == NULL) {
jclass sequencedEventClsLocal
= env->FindClass("java/awt/SequencedEvent");
DASSERT(sequencedEventClsLocal);
if (sequencedEventClsLocal == NULL) {
/* exception already thrown */
return;
}
sequencedEventCls =
(jclass)env->NewGlobalRef(sequencedEventClsLocal);
env->DeleteLocalRef(sequencedEventClsLocal);
}
static jmethodID sequencedEventConst;
if (sequencedEventConst == NULL) {
sequencedEventConst =
env->GetMethodID(sequencedEventCls, "<init>",
"(Ljava/awt/AWTEvent;)V");
}
if (env->EnsureLocalCapacity(3) < 0) {
return;
}
jobject target = GetTarget(env);
jobject jOpposite = NULL;
if (opposite != NULL) {
AwtComponent *awtOpposite = AwtComponent::GetComponent(opposite);
if (awtOpposite != NULL) {
jOpposite = awtOpposite->GetTarget(env);
}
}
jobject event = env->NewObject(wClassEvent, wEventInitMID, target, id,
jOpposite, oldState, newState, TimeHelper::getMessageTimeUTC());
DASSERT(!safe_ExceptionOccurred(env));
DASSERT(event != NULL);
if (jOpposite != NULL) {
env->DeleteLocalRef(jOpposite); jOpposite = NULL;
}
env->DeleteLocalRef(target); target = NULL;
if (id == java_awt_event_WindowEvent_WINDOW_GAINED_FOCUS ||
id == java_awt_event_WindowEvent_WINDOW_LOST_FOCUS)
{
jobject sequencedEvent = env->NewObject(sequencedEventCls,
sequencedEventConst,
event);
DASSERT(!safe_ExceptionOccurred(env));
DASSERT(sequencedEvent != NULL);
env->DeleteLocalRef(event);
event = sequencedEvent;
}
SendEvent(event);
env->DeleteLocalRef(event);
}
BOOL AwtWindow::AwtSetActiveWindow(BOOL isMouseEventCause, UINT hittest)
{
// We used to reject non mouse window activation if our app wasn't active.
// This code since has been removed as the fix for 7185280
HWND proxyContainerHWnd = GetProxyToplevelContainer();
HWND proxyHWnd = GetProxyFocusOwner();
if (proxyContainerHWnd == NULL || proxyHWnd == NULL) {
return FALSE;
}
// Activate the proxy toplevel container
if (::GetActiveWindow() != proxyContainerHWnd) {
sm_suppressFocusAndActivation = TRUE;
::BringWindowToTop(proxyContainerHWnd);
::SetForegroundWindow(proxyContainerHWnd);
sm_suppressFocusAndActivation = FALSE;
if (::GetActiveWindow() != proxyContainerHWnd) {
return FALSE; // activation has been rejected
}
}
// Focus the proxy itself
if (::GetFocus() != proxyHWnd) {
sm_suppressFocusAndActivation = TRUE;
::SetFocus(proxyHWnd);
sm_suppressFocusAndActivation = FALSE;
if (::GetFocus() != proxyHWnd) {
return FALSE; // focus has been rejected (that is unlikely)
}
}
const HWND focusedWindow = AwtComponent::GetFocusedWindow();
if (focusedWindow != GetHWnd()) {
if (focusedWindow != NULL) {
// Deactivate the old focused window
AwtWindow::SynthesizeWmActivate(FALSE, focusedWindow, GetHWnd());
}
// Activate the new focused window.
AwtWindow::SynthesizeWmActivate(TRUE, GetHWnd(), focusedWindow);
}
return TRUE;
}
MsgRouting AwtWindow::WmActivate(UINT nState, BOOL fMinimized, HWND opposite)
{
jint type;
if (nState != WA_INACTIVE) {
type = java_awt_event_WindowEvent_WINDOW_GAINED_FOCUS;
AwtComponent::SetFocusedWindow(GetHWnd());
} else {
// The owner is not necassarily getting WM_ACTIVATE(WA_INACTIVE).
// So, initiate retaining the actualFocusedWindow.
AwtFrame *owner = GetOwningFrameOrDialog();
if (owner) {
owner->CheckRetainActualFocusedWindow(opposite);
}
if (m_grabbedWindow != NULL && !m_grabbedWindow->IsOneOfOwnersOf(this)) {
m_grabbedWindow->Ungrab();
}
type = java_awt_event_WindowEvent_WINDOW_LOST_FOCUS;
AwtComponent::SetFocusedWindow(NULL);
sm_focusOwner = NULL;
}
SendWindowEvent(type, opposite);
return mrConsume;
}
MsgRouting AwtWindow::WmCreate()
{
return mrDoDefault;
}
MsgRouting AwtWindow::WmClose()
{
SendWindowEvent(java_awt_event_WindowEvent_WINDOW_CLOSING);
/* Rely on above notification to handle quitting as needed */
return mrConsume;
}
MsgRouting AwtWindow::WmDestroy()
{
SendWindowEvent(java_awt_event_WindowEvent_WINDOW_CLOSED);
return AwtComponent::WmDestroy();
}
MsgRouting AwtWindow::WmShowWindow(BOOL show, UINT status)
{
/*
* Original fix for 4810575. Modified for 6386592.
* If a simple window gets disposed we should synthesize
* WM_ACTIVATE for its nearest owner. This is not performed by default because
* the owner frame/dialog is natively active.
*/
HWND hwndSelf = GetHWnd();
HWND hwndOwner = ::GetParent(hwndSelf);
if (!show && IsSimpleWindow() && hwndSelf == AwtComponent::GetFocusedWindow() &&
hwndOwner != NULL && ::IsWindowVisible(hwndOwner))
{
AwtFrame *owner = (AwtFrame*)AwtComponent::GetComponent(hwndOwner);
if (owner != NULL) {
owner->AwtSetActiveWindow();
}
}
//Fixed 4842599: REGRESSION: JPopupMenu not Hidden Properly After Iconified and Deiconified
if (show && (status == SW_PARENTOPENING)) {
if (!IsVisible()) {
return mrConsume;
}
}
return AwtCanvas::WmShowWindow(show, status);
}
/*
* Override AwtComponent's move handling to first update the
* java AWT target's position fields directly, since Windows
* and below can be resized from outside of java (by user)
*/
MsgRouting AwtWindow::WmMove(int x, int y)
{
if ( ::IsIconic(GetHWnd()) ) {
// fixes 4065534 (robi.khan@eng)
// if a window is iconified we don't want to update
// it's target's position since minimized Win32 windows
// move to -32000, -32000 for whatever reason
// NOTE: See also AwtWindow::Reshape
return mrDoDefault;
}
if (m_screenNum == -1) {
// Set initial value
m_screenNum = GetScreenImOn();
}
else {
CheckIfOnNewScreen();
}
/* Update the java AWT target component's fields directly */
JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
if (env->EnsureLocalCapacity(1) < 0) {
return mrConsume;
}
jobject peer = GetPeer(env);
jobject target = env->GetObjectField(peer, AwtObject::targetID);
RECT rect;
::GetWindowRect(GetHWnd(), &rect);
(env)->SetIntField(target, AwtComponent::xID, rect.left);
(env)->SetIntField(target, AwtComponent::yID, rect.top);
(env)->SetIntField(peer, AwtWindow::sysXID, rect.left);
(env)->SetIntField(peer, AwtWindow::sysYID, rect.top);
SendComponentEvent(java_awt_event_ComponentEvent_COMPONENT_MOVED);
env->DeleteLocalRef(target);
return AwtComponent::WmMove(x, y);
}
MsgRouting AwtWindow::WmGetMinMaxInfo(LPMINMAXINFO lpmmi)
{
MsgRouting r = AwtCanvas::WmGetMinMaxInfo(lpmmi);
if ((m_minSize.x == 0) && (m_minSize.y == 0)) {
return r;
}
lpmmi->ptMinTrackSize.x = m_minSize.x;
lpmmi->ptMinTrackSize.y = m_minSize.y;
return mrConsume;
}
MsgRouting AwtWindow::WmSizing()
{
if (!AwtToolkit::GetInstance().IsDynamicLayoutActive()) {
return mrDoDefault;
}
DTRACE_PRINTLN("AwtWindow::WmSizing fullWindowDragEnabled");
SendComponentEvent(java_awt_event_ComponentEvent_COMPONENT_RESIZED);
HWND thisHwnd = GetHWnd();
if (thisHwnd == NULL) {
return mrDoDefault;
}
// Call WComponentPeer::dynamicallyLayoutContainer()
JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
jobject peer = GetPeer(env);
JNU_CallMethodByName(env, NULL, peer, "dynamicallyLayoutContainer", "()V");
DASSERT(!safe_ExceptionOccurred(env));
return mrDoDefault;
}
/*
* Override AwtComponent's size handling to first update the
* java AWT target's dimension fields directly, since Windows
* and below can be resized from outside of java (by user)
*/
MsgRouting AwtWindow::WmSize(UINT type, int w, int h)
{
currentWmSizeState = type;
if (type == SIZE_MINIMIZED) {
UpdateSecurityWarningVisibility();
return mrDoDefault;
}
JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
if (env->EnsureLocalCapacity(1) < 0)
return mrDoDefault;
jobject target = GetTarget(env);
// fix 4167248 : ensure the insets are up-to-date before using
BOOL insetsChanged = UpdateInsets(NULL);
int newWidth = w + m_insets.left + m_insets.right;
int newHeight = h + m_insets.top + m_insets.bottom;
(env)->SetIntField(target, AwtComponent::widthID, newWidth);
(env)->SetIntField(target, AwtComponent::heightID, newHeight);
jobject peer = GetPeer(env);
(env)->SetIntField(peer, AwtWindow::sysWID, newWidth);
(env)->SetIntField(peer, AwtWindow::sysHID, newHeight);
if (!AwtWindow::IsResizing()) {
WindowResized();
}
env->DeleteLocalRef(target);
return AwtComponent::WmSize(type, w, h);
}
MsgRouting AwtWindow::WmPaint(HDC)
{
PaintUpdateRgn(&m_insets);
return mrConsume;
}
MsgRouting AwtWindow::WmSettingChange(UINT wFlag, LPCTSTR pszSection)
{
if (wFlag == SPI_SETNONCLIENTMETRICS) {
// user changed window metrics in
// Control Panel->Display->Appearance
// which may cause window insets to change
UpdateInsets(NULL);
// [rray] fix for 4407329 - Changing Active Window Border width in display
// settings causes problems
WindowResized();
Invalidate(NULL);
return mrConsume;
}
return mrDoDefault;
}
MsgRouting AwtWindow::WmNcCalcSize(BOOL fCalcValidRects,
LPNCCALCSIZE_PARAMS lpncsp, LRESULT& retVal)
{
MsgRouting mrRetVal = mrDoDefault;
if (fCalcValidRects == FALSE) {
return mrDoDefault;
}
JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
if (env->EnsureLocalCapacity(2) < 0) {
return mrConsume;
}
// WM_NCCALCSIZE is usually in response to a resize, but
// also can be triggered by SetWindowPos(SWP_FRAMECHANGED),
// which means the insets will have changed - rnk 4/7/1998
retVal = static_cast<UINT>(DefWindowProc(
WM_NCCALCSIZE, fCalcValidRects, reinterpret_cast<LPARAM>(lpncsp)));
if (HasValidRect()) {
UpdateInsets(NULL);
}
mrRetVal = mrConsume;
return mrRetVal;
}
MsgRouting AwtWindow::WmNcHitTest(UINT x, UINT y, LRESULT& retVal)
{
// If this window is blocked by modal dialog, return HTCLIENT for any point of it.
// That prevents it to be moved or resized using the mouse. Disabling these
// actions to be launched from sysmenu is implemented by ignoring WM_SYSCOMMAND
if (::IsWindow(GetModalBlocker(GetHWnd()))) {
retVal = HTCLIENT;
} else {
retVal = DefWindowProc(WM_NCHITTEST, 0, MAKELPARAM(x, y));
}
return mrConsume;
}
MsgRouting AwtWindow::WmGetIcon(WPARAM iconType, LRESULT& retValue)
{
return mrDoDefault;
}
LRESULT AwtWindow::WindowProc(UINT message, WPARAM wParam, LPARAM lParam)
{
MsgRouting mr = mrDoDefault;
LRESULT retValue = 0L;
switch(message) {
case WM_GETICON:
mr = WmGetIcon(wParam, retValue);
break;
case WM_SYSCOMMAND:
//Fixed 6355340: Contents of frame are not layed out properly on maximize
if ((wParam & 0xFFF0) == SC_SIZE) {
AwtWindow::sm_resizing = TRUE;
mr = WmSysCommand(wParam, GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam));
if (mr != mrConsume) {
// Perform size-move loop here
AwtWindow::DefWindowProc(message, wParam, lParam);
}
AwtWindow::sm_resizing = FALSE;
if (!AwtToolkit::GetInstance().IsDynamicLayoutActive()) {
WindowResized();
} else {
/*
* 8016356: check whether window snapping occurred after
* resizing, i.e. GetWindowRect() returns the real
* (snapped) window rectangle, e.g. (179, 0)-(483, 1040),
* but GetWindowPlacement() returns the rectangle of
* normal window position, e.g. (179, 189)-(483, 445) and
* they are different. If so, send ComponentResized event.
*/
WINDOWPLACEMENT wp;
::GetWindowPlacement(GetHWnd(), &wp);
RECT rc;
::GetWindowRect(GetHWnd(), &rc);
if (!::EqualRect(&rc, &wp.rcNormalPosition)) {
WindowResized();
}
}
mr = mrConsume;
}
break;
}
if (mr != mrConsume) {
retValue = AwtCanvas::WindowProc(message, wParam, lParam);
}
return retValue;
}
/*
* Fix for BugTraq ID 4041703: keyDown not being invoked.
* This method overrides AwtCanvas::HandleEvent() since
* an empty Window always receives the focus on the activation
* so we don't have to modify the behavior.
*/
MsgRouting AwtWindow::HandleEvent(MSG *msg, BOOL synthetic)
{
return AwtComponent::HandleEvent(msg, synthetic);
}
void AwtWindow::WindowResized()
{
SendComponentEvent(java_awt_event_ComponentEvent_COMPONENT_RESIZED);
// Need to replace surfaceData on resize to catch changes to
// various component-related values, such as insets
JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
env->CallVoidMethod(m_peerObject, AwtComponent::replaceSurfaceDataLaterMID);
}
BOOL CALLBACK InvalidateChildRect(HWND hWnd, LPARAM)
{
TRY;
::InvalidateRect(hWnd, NULL, TRUE);
return TRUE;
CATCH_BAD_ALLOC_RET(FALSE);
}
void AwtWindow::Invalidate(RECT* r)
{
::InvalidateRect(GetHWnd(), NULL, TRUE);
::EnumChildWindows(GetHWnd(), (WNDENUMPROC)InvalidateChildRect, 0);
}
BOOL AwtWindow::IsResizable() {
return m_isResizable;
}
void AwtWindow::SetResizable(BOOL isResizable)
{
m_isResizable = isResizable;
if (IsEmbeddedFrame()) {
return;
}
LONG style = GetStyle();
LONG resizeStyle = WS_MAXIMIZEBOX;
if (IsUndecorated() == FALSE) {
resizeStyle |= WS_THICKFRAME;
}
if (isResizable) {
style |= resizeStyle;
} else {
style &= ~resizeStyle;
}
SetStyle(style);
RedrawNonClient();
}
// SetWindowPos flags to cause frame edge to be recalculated
static const UINT SwpFrameChangeFlags =
SWP_FRAMECHANGED | /* causes WM_NCCALCSIZE to be called */
SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER |
SWP_NOACTIVATE | SWP_NOCOPYBITS |
SWP_NOREPOSITION | SWP_NOSENDCHANGING;
//
// Forces WM_NCCALCSIZE to be called to recalculate
// window border (updates insets) without redrawing it
//
void AwtWindow::RecalcNonClient()
{
::SetWindowPos(GetHWnd(), (HWND) NULL, 0, 0, 0, 0, SwpFrameChangeFlags|SWP_NOREDRAW);
}
//
// Forces WM_NCCALCSIZE to be called to recalculate
// window border (updates insets) and redraws border to match
//
void AwtWindow::RedrawNonClient()
{
::SetWindowPos(GetHWnd(), (HWND) NULL, 0, 0, 0, 0, SwpFrameChangeFlags|SWP_ASYNCWINDOWPOS);
}
int AwtWindow::GetScreenImOn() {
HMONITOR hmon;
int scrnNum;
hmon = ::MonitorFromWindow(GetHWnd(), MONITOR_DEFAULTTOPRIMARY);
DASSERT(hmon != NULL);
scrnNum = AwtWin32GraphicsDevice::GetScreenFromHMONITOR(hmon);
DASSERT(scrnNum > -1);
return scrnNum;
}
/* Check to see if we've been moved onto another screen.
* If so, update internal data, surfaces, etc.
*/
void AwtWindow::CheckIfOnNewScreen() {
int curScrn = GetScreenImOn();
if (curScrn != m_screenNum) { // we've been moved
JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
jclass peerCls = env->GetObjectClass(m_peerObject);
DASSERT(peerCls);
jmethodID draggedID = env->GetMethodID(peerCls, "draggedToNewScreen",
"()V");
DASSERT(draggedID);
env->CallVoidMethod(m_peerObject, draggedID);
m_screenNum = curScrn;
env->DeleteLocalRef(peerCls);
}
}
BOOL AwtWindow::IsFocusableWindow() {
/*
* For Window/Frame/Dialog to accept focus it should:
* - be focusable;
* - be not blocked by any modal blocker.
*/
BOOL focusable = m_isFocusableWindow && !::IsWindow(AwtWindow::GetModalBlocker(GetHWnd()));
AwtFrame *owner = GetOwningFrameOrDialog(); // NULL for Frame and Dialog
if (owner != NULL) {
/*
* Also for Window (not Frame/Dialog) to accept focus:
* - its decorated parent should accept focus;
*/
focusable = focusable && owner->IsFocusableWindow();
}
return focusable;
}
void AwtWindow::SetModalBlocker(HWND window, HWND blocker) {
if (!::IsWindow(window)) {
return;
}
if (::IsWindow(blocker)) {
::SetProp(window, ModalBlockerProp, reinterpret_cast<HANDLE>(blocker));
::EnableWindow(window, FALSE);
} else {
::RemoveProp(window, ModalBlockerProp);
AwtComponent *comp = AwtComponent::GetComponent(window);
// we don't expect to be called with non-java HWNDs
DASSERT(comp && comp->IsTopLevel());
// we should not unblock disabled toplevels
::EnableWindow(window, comp->isEnabled());
}
}
void AwtWindow::SetAndActivateModalBlocker(HWND window, HWND blocker) {
if (!::IsWindow(window)) {
return;
}
AwtWindow::SetModalBlocker(window, blocker);
if (::IsWindow(blocker)) {
// We must check for visibility. Otherwise invisible dialog will receive WM_ACTIVATE.
if (::IsWindowVisible(blocker)) {
::BringWindowToTop(blocker);
::SetForegroundWindow(blocker);
}
}
}
HWND AwtWindow::GetTopmostModalBlocker(HWND window)
{
HWND ret, blocker = NULL;
do {
ret = blocker;
blocker = AwtWindow::GetModalBlocker(window);
window = blocker;
} while (::IsWindow(blocker));
return ret;
}
void AwtWindow::FlashWindowEx(HWND hWnd, UINT count, DWORD timeout, DWORD flags) {
FLASHWINFO fi;
fi.cbSize = sizeof(fi);
fi.hwnd = hWnd;
fi.dwFlags = flags;
fi.uCount = count;
fi.dwTimeout = timeout;
::FlashWindowEx(&fi);
}
jboolean
AwtWindow::_RequestWindowFocus(void *param)
{
JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
RequestWindowFocusStruct *rfs = (RequestWindowFocusStruct *)param;
jobject self = rfs->component;
jboolean isMouseEventCause = rfs->isMouseEventCause;
jboolean result = JNI_FALSE;
AwtWindow *window = NULL;
PDATA pData;
JNI_CHECK_NULL_GOTO(self, "peer", ret);
pData = JNI_GET_PDATA(self);
if (pData == NULL) {
// do nothing just return false
goto ret;
}
window = (AwtWindow *)pData;
if (::IsWindow(window->GetHWnd())) {
result = (jboolean)window->SendMessage(WM_AWT_WINDOW_SETACTIVE, (WPARAM)isMouseEventCause, 0);
}
ret:
env->DeleteGlobalRef(self);
delete rfs;
return result;
}
void AwtWindow::_ToFront(void *param)
{
JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
jobject self = (jobject)param;
AwtWindow *w = NULL;
PDATA pData;
JNI_CHECK_PEER_GOTO(self, ret);
w = (AwtWindow *)pData;
if (::IsWindow(w->GetHWnd()))
{
UINT flags = SWP_NOMOVE|SWP_NOSIZE;
BOOL focusable = w->IsFocusableWindow();
BOOL autoRequestFocus = w->IsAutoRequestFocus();
if (!focusable || !autoRequestFocus)
{
flags = flags|SWP_NOACTIVATE;
}
::SetWindowPos(w->GetHWnd(), HWND_TOP, 0, 0, 0, 0, flags);
if (focusable && autoRequestFocus)
{
::SetForegroundWindow(w->GetHWnd());
}
}
ret:
env->DeleteGlobalRef(self);
}
void AwtWindow::_ToBack(void *param)
{
JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
jobject self = (jobject)param;
AwtWindow *w = NULL;
PDATA pData;
JNI_CHECK_PEER_GOTO(self, ret);
w = (AwtWindow *)pData;
if (::IsWindow(w->GetHWnd()))
{
HWND hwnd = w->GetHWnd();
// if (AwtComponent::GetComponent(hwnd) == NULL) {
// // Window was disposed. Don't bother.
// return;
// }
::SetWindowPos(hwnd, HWND_BOTTOM, 0, 0 ,0, 0,
SWP_NOMOVE|SWP_NOSIZE|SWP_NOACTIVATE);
// If hwnd is the foreground window or if *any* of its owners are, then
// we have to reset the foreground window. The reason is that when we send
// hwnd to back, all of its owners are sent to back as well. If any one of
// them is the foreground window, then it's possible that we could end up
// with a foreground window behind a window of another application.
HWND foregroundWindow = ::GetForegroundWindow();
BOOL adjustForegroundWindow;
HWND toTest = hwnd;
do
{
adjustForegroundWindow = (toTest == foregroundWindow);
if (adjustForegroundWindow)
{
break;
}
toTest = ::GetWindow(toTest, GW_OWNER);
}
while (toTest != NULL);
if (adjustForegroundWindow)
{
HWND foregroundSearch = hwnd, newForegroundWindow = NULL;
while (1)
{
foregroundSearch = ::GetNextWindow(foregroundSearch, GW_HWNDPREV);
if (foregroundSearch == NULL)
{
break;
}
LONG style = static_cast<LONG>(::GetWindowLongPtr(foregroundSearch, GWL_STYLE));
if ((style & WS_CHILD) || !(style & WS_VISIBLE))
{
continue;
}
AwtComponent *c = AwtComponent::GetComponent(foregroundSearch);
if ((c != NULL) && !::IsWindow(AwtWindow::GetModalBlocker(c->GetHWnd())))
{
newForegroundWindow = foregroundSearch;
}
}
if (newForegroundWindow != NULL)
{
::SetWindowPos(newForegroundWindow, HWND_TOP, 0, 0, 0, 0,
SWP_NOMOVE|SWP_NOSIZE|SWP_NOACTIVATE);
if (((AwtWindow*)AwtComponent::GetComponent(newForegroundWindow))->IsFocusableWindow())
{
::SetForegroundWindow(newForegroundWindow);
}
}
else
{
// We *have* to set the active HWND to something new. We simply
// cannot risk having an active Java HWND which is behind an HWND
// of a native application. This really violates the Windows user
// experience.
//
// Windows won't allow us to set the foreground window to NULL,
// so we use the desktop window instead. To the user, it appears
// that there is no foreground window system-wide.
::SetForegroundWindow(::GetDesktopWindow());
}
}
}
ret:
env->DeleteGlobalRef(self);
}
void AwtWindow::_SetAlwaysOnTop(void *param)
{
JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
SetAlwaysOnTopStruct *sas = (SetAlwaysOnTopStruct *)param;
jobject self = sas->window;
jboolean value = sas->value;
AwtWindow *w = NULL;
PDATA pData;
JNI_CHECK_PEER_GOTO(self, ret);
w = (AwtWindow *)pData;
if (::IsWindow(w->GetHWnd()))
{
w->SendMessage(WM_AWT_SETALWAYSONTOP, (WPARAM)value, (LPARAM)w);
w->m_alwaysOnTop = (bool)value;
}
ret:
env->DeleteGlobalRef(self);
delete sas;
}
void AwtWindow::_SetTitle(void *param)
{
JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
SetTitleStruct *sts = (SetTitleStruct *)param;
jobject self = sts->window;
jstring title = sts->title;
AwtWindow *w = NULL;
PDATA pData;
JNI_CHECK_PEER_GOTO(self, ret);
JNI_CHECK_NULL_GOTO(title, "null title", ret);
w = (AwtWindow *)pData;
if (::IsWindow(w->GetHWnd()))
{
int length = env->GetStringLength(title);
TCHAR *buffer = new TCHAR[length + 1];
env->GetStringRegion(title, 0, length, reinterpret_cast<jchar*>(buffer));
buffer[length] = L'\0';
VERIFY(::SetWindowText(w->GetHWnd(), buffer));
delete[] buffer;
}
ret:
env->DeleteGlobalRef(self);
if (title != NULL) {
env->DeleteGlobalRef(title);
}
delete sts;
}
void AwtWindow::_SetResizable(void *param)
{
JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
SetResizableStruct *srs = (SetResizableStruct *)param;
jobject self = srs->window;
jboolean resizable = srs->resizable;
AwtWindow *w = NULL;
PDATA pData;
JNI_CHECK_PEER_GOTO(self, ret);
w = (AwtWindow *)pData;
if (::IsWindow(w->GetHWnd()))
{
DASSERT(!IsBadReadPtr(w, sizeof(AwtWindow)));
w->SetResizable(resizable != 0);
}
ret:
env->DeleteGlobalRef(self);
delete srs;
}
void AwtWindow::_UpdateInsets(void *param)
{
JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
UpdateInsetsStruct *uis = (UpdateInsetsStruct *)param;
jobject self = uis->window;
jobject insets = uis->insets;
AwtWindow *w = NULL;
PDATA pData;
JNI_CHECK_PEER_GOTO(self, ret);
JNI_CHECK_NULL_GOTO(insets, "null insets", ret);
w = (AwtWindow *)pData;
if (::IsWindow(w->GetHWnd()))
{
w->UpdateInsets(insets);
}
ret:
env->DeleteGlobalRef(self);
env->DeleteGlobalRef(insets);
delete uis;
}
void AwtWindow::_ReshapeFrame(void *param)
{
JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
ReshapeFrameStruct *rfs = (ReshapeFrameStruct *)param;
jobject self = rfs->frame;
jint x = rfs->x;
jint y = rfs->y;
jint w = rfs->w;
jint h = rfs->h;
if (env->EnsureLocalCapacity(1) < 0)
{
env->DeleteGlobalRef(self);
delete rfs;
return;
}
AwtFrame *p = NULL;
PDATA pData;
JNI_CHECK_PEER_GOTO(self, ret);
p = (AwtFrame *)pData;
if (::IsWindow(p->GetHWnd()))
{
jobject target = env->GetObjectField(self, AwtObject::targetID);
if (target != NULL)
{
// enforce tresholds before sending the event
// Fix for 4459064 : do not enforce thresholds for embedded frames
if (!p->IsEmbeddedFrame())
{
jobject peer = p->GetPeer(env);
int minWidth = ::GetSystemMetrics(SM_CXMIN);
int minHeight = ::GetSystemMetrics(SM_CYMIN);
if (w < minWidth)
{
env->SetIntField(target, AwtComponent::widthID,
w = minWidth);
env->SetIntField(peer, AwtWindow::sysWID,
w);
}
if (h < minHeight)
{
env->SetIntField(target, AwtComponent::heightID,
h = minHeight);
env->SetIntField(peer, AwtWindow::sysHID,
h);
}
}
env->DeleteLocalRef(target);
RECT *r = new RECT;
::SetRect(r, x, y, x + w, y + h);
p->SendMessage(WM_AWT_RESHAPE_COMPONENT, 0, (LPARAM)r);
// r is deleted in message handler
// After the input method window shown, the dimension & position may not
// be valid until this method is called. So we need to adjust the
// IME candidate window position for the same reason as commented on
// awt_Frame.cpp Show() method.
if (p->isInputMethodWindow() && ::IsWindowVisible(p->GetHWnd())) {
p->AdjustCandidateWindowPos();
}
}
else
{
JNU_ThrowNullPointerException(env, "null target");
}
}
ret:
env->DeleteGlobalRef(self);
delete rfs;
}
/*
* This is AwtWindow-specific function that is not intended for reusing
*/
HICON CreateIconFromRaster(JNIEnv* env, jintArray iconRaster, jint w, jint h)
{
HBITMAP mask = NULL;
HBITMAP image = NULL;
HICON icon = NULL;
if (iconRaster != NULL) {
int* iconRasterBuffer = NULL;
try {
iconRasterBuffer = (int *)env->GetPrimitiveArrayCritical(iconRaster, 0);
JNI_CHECK_NULL_GOTO(iconRasterBuffer, "iconRaster data", done);
mask = BitmapUtil::CreateTransparencyMaskFromARGB(w, h, iconRasterBuffer);
image = BitmapUtil::CreateV4BitmapFromARGB(w, h, iconRasterBuffer);
} catch (...) {
if (iconRasterBuffer != NULL) {
env->ReleasePrimitiveArrayCritical(iconRaster, iconRasterBuffer, 0);
}
throw;
}
if (iconRasterBuffer != NULL) {
env->ReleasePrimitiveArrayCritical(iconRaster, iconRasterBuffer, 0);
}
}
if (mask && image) {
ICONINFO icnInfo;
memset(&icnInfo, 0, sizeof(ICONINFO));
icnInfo.hbmMask = mask;
icnInfo.hbmColor = image;
icnInfo.fIcon = TRUE;
icon = ::CreateIconIndirect(&icnInfo);
}
if (image) {
destroy_BMP(image);
}
if (mask) {
destroy_BMP(mask);
}
done:
return icon;
}
void AwtWindow::SetIconData(JNIEnv* env, jintArray iconRaster, jint w, jint h,
jintArray smallIconRaster, jint smw, jint smh)
{
HICON hOldIcon = NULL;
HICON hOldIconSm = NULL;
//Destroy previous icon if it isn't inherited
if ((m_hIcon != NULL) && !m_iconInherited) {
hOldIcon = m_hIcon;
}
m_hIcon = NULL;
if ((m_hIconSm != NULL) && !m_iconInherited) {
hOldIconSm = m_hIconSm;
}
m_hIconSm = NULL;
m_hIcon = CreateIconFromRaster(env, iconRaster, w, h);
m_hIconSm = CreateIconFromRaster(env, smallIconRaster, smw, smh);
m_iconInherited = (m_hIcon == NULL);
if (m_iconInherited) {
HWND hOwner = ::GetWindow(GetHWnd(), GW_OWNER);
AwtWindow* owner = (AwtWindow *)AwtComponent::GetComponent(hOwner);
if (owner != NULL) {
m_hIcon = owner->GetHIcon();
m_hIconSm = owner->GetHIconSm();
} else {
m_iconInherited = FALSE;
}
}
DoUpdateIcon();
EnumThreadWindows(AwtToolkit::MainThread(), UpdateOwnedIconCallback, (LPARAM)this);
if (hOldIcon != NULL) {
DestroyIcon(hOldIcon);
}
if (hOldIconSm != NULL) {
DestroyIcon(hOldIconSm);
}
}
BOOL AwtWindow::UpdateOwnedIconCallback(HWND hWndOwned, LPARAM lParam)
{
HWND hWndOwner = ::GetWindow(hWndOwned, GW_OWNER);
AwtWindow* owner = (AwtWindow*)lParam;
if (hWndOwner == owner->GetHWnd()) {
AwtComponent* comp = AwtComponent::GetComponent(hWndOwned);
if (comp != NULL && comp->IsTopLevel()) {
AwtWindow* owned = (AwtWindow *)comp;
if (owned->m_iconInherited) {
owned->m_hIcon = owner->m_hIcon;
owned->m_hIconSm = owner->m_hIconSm;
owned->DoUpdateIcon();
EnumThreadWindows(AwtToolkit::MainThread(), UpdateOwnedIconCallback, (LPARAM)owned);
}
}
}
return TRUE;
}
void AwtWindow::DoUpdateIcon()
{
//Does nothing for windows, is overriden for frames and dialogs
}
void AwtWindow::RedrawWindow()
{
if (isOpaque()) {
::RedrawWindow(GetHWnd(), NULL, NULL,
RDW_ERASE | RDW_INVALIDATE | RDW_FRAME | RDW_ALLCHILDREN);
} else {
::EnterCriticalSection(&contentBitmapCS);
if (hContentBitmap != NULL) {
UpdateWindowImpl(contentWidth, contentHeight, hContentBitmap);
}
::LeaveCriticalSection(&contentBitmapCS);
}
}
// Deletes the hContentBitmap if it is non-null
void AwtWindow::DeleteContentBitmap()
{
::EnterCriticalSection(&contentBitmapCS);
if (hContentBitmap != NULL) {
::DeleteObject(hContentBitmap);
hContentBitmap = NULL;
}
::LeaveCriticalSection(&contentBitmapCS);
}
// The effects are enabled only upon showing the window.
// See 6780496 for details.
void AwtWindow::EnableTranslucency(BOOL enable)
{
if (enable) {
SetTranslucency(getOpacity(), isOpaque(), FALSE, TRUE);
} else {
SetTranslucency(0xFF, TRUE, FALSE);
}
}
/**
* Sets the translucency effects.
*
* This method is used to:
*
* 1. Apply the translucency effects upon showing the window
* (setValues == FALSE, useDefaultForOldValues == TRUE);
* 2. Turn off the effects upon hiding the window
* (setValues == FALSE, useDefaultForOldValues == FALSE);
* 3. Set the effects per user's request
* (setValues == TRUE, useDefaultForOldValues == FALSE);
*
* In case #3 the effects may or may not be applied immediately depending on
* the current visibility status of the window.
*
* The setValues argument indicates if we need to preserve the passed values
* in local fields for further use.
* The useDefaultForOldValues argument indicates whether we should consider
* the window as if it has not any effects applied at the moment.
*/
void AwtWindow::SetTranslucency(BYTE opacity, BOOL opaque, BOOL setValues,
BOOL useDefaultForOldValues)
{
BYTE old_opacity = useDefaultForOldValues ? 0xFF : getOpacity();
BOOL old_opaque = useDefaultForOldValues ? TRUE : isOpaque();
if (opacity == old_opacity && opaque == old_opaque) {
return;
}
if (setValues) {
m_opacity = opacity;
m_opaque = opaque;
}
// If we're invisible and are storing the values, return
// Otherwise, apply the effects immediately
if (!IsVisible() && setValues) {
return;
}
HWND hwnd = GetHWnd();
if (opaque != old_opaque) {
DeleteContentBitmap();
}
if (opaque && opacity == 0xff) {
// Turn off all the effects
AwtWindow::SetLayered(hwnd, false);
// Ask the window to repaint itself and all the children
RedrawWindow();
} else {
// We're going to enable some effects
if (!AwtWindow::IsLayered(hwnd)) {
AwtWindow::SetLayered(hwnd, true);
} else {
if ((opaque && opacity < 0xff) ^ (old_opaque && old_opacity < 0xff)) {
// _One_ of the modes uses the SetLayeredWindowAttributes.
// Need to reset the style in this case.
// If both modes are simple (i.e. just changing the opacity level),
// no need to reset the style.
AwtWindow::SetLayered(hwnd, false);
AwtWindow::SetLayered(hwnd, true);
}
}
if (opaque) {
// Simple opacity mode
::SetLayeredWindowAttributes(hwnd, RGB(0, 0, 0), opacity, LWA_ALPHA);
}
}
}
static HBITMAP CreateBitmapFromRaster(JNIEnv* env, jintArray raster, jint w, jint h)
{
HBITMAP image = NULL;
if (raster != NULL) {
int* rasterBuffer = NULL;
try {
rasterBuffer = (int *)env->GetPrimitiveArrayCritical(raster, 0);
JNI_CHECK_NULL_GOTO(rasterBuffer, "raster data", done);
image = BitmapUtil::CreateBitmapFromARGBPre(w, h, w*4, rasterBuffer);
} catch (...) {
if (rasterBuffer != NULL) {
env->ReleasePrimitiveArrayCritical(raster, rasterBuffer, 0);
}
throw;
}
if (rasterBuffer != NULL) {
env->ReleasePrimitiveArrayCritical(raster, rasterBuffer, 0);
}
}
done:
return image;
}
void AwtWindow::UpdateWindowImpl(int width, int height, HBITMAP hBitmap)
{
if (isOpaque()) {
return;
}
HWND hWnd = GetHWnd();
HDC hdcDst = ::GetDC(NULL);
HDC hdcSrc = ::CreateCompatibleDC(NULL);
HBITMAP hOldBitmap = (HBITMAP)::SelectObject(hdcSrc, hBitmap);
//XXX: this code doesn't paint the children (say, the java.awt.Button)!
//So, if we ever want to support HWs here, we need to repaint them
//in some other way...
//::SendMessage(hWnd, WM_PRINT, (WPARAM)hdcSrc, /*PRF_CHECKVISIBLE |*/
// PRF_CHILDREN /*| PRF_CLIENT | PRF_NONCLIENT*/);
POINT ptSrc;
ptSrc.x = ptSrc.y = 0;
RECT rect;
POINT ptDst;
SIZE size;
::GetWindowRect(hWnd, &rect);
ptDst.x = rect.left;
ptDst.y = rect.top;
size.cx = width;
size.cy = height;
BLENDFUNCTION bf;
bf.SourceConstantAlpha = getOpacity();
bf.AlphaFormat = AC_SRC_ALPHA;
bf.BlendOp = AC_SRC_OVER;
bf.BlendFlags = 0;
::UpdateLayeredWindow(hWnd, hdcDst, &ptDst, &size, hdcSrc, &ptSrc,
RGB(0, 0, 0), &bf, ULW_ALPHA);
::ReleaseDC(NULL, hdcDst);
::SelectObject(hdcSrc, hOldBitmap);
::DeleteDC(hdcSrc);
}
void AwtWindow::UpdateWindow(JNIEnv* env, jintArray data, int width, int height,
HBITMAP hNewBitmap)
{
if (isOpaque()) {
return;
}
HBITMAP hBitmap;
if (hNewBitmap == NULL) {
if (data == NULL) {
return;
}
hBitmap = CreateBitmapFromRaster(env, data, width, height);
if (hBitmap == NULL) {
return;
}
} else {
hBitmap = hNewBitmap;
}
::EnterCriticalSection(&contentBitmapCS);
DeleteContentBitmap();
hContentBitmap = hBitmap;
contentWidth = width;
contentHeight = height;
UpdateWindowImpl(width, height, hBitmap);
::LeaveCriticalSection(&contentBitmapCS);
}
/*
* Fixed 6353381: it's improved fix for 4792958
* which was backed-out to avoid 5059656
*/
BOOL AwtWindow::HasValidRect()
{
RECT inside;
RECT outside;
if (::IsIconic(GetHWnd())) {
return FALSE;
}
::GetClientRect(GetHWnd(), &inside);
::GetWindowRect(GetHWnd(), &outside);
BOOL isZeroClientArea = (inside.right == 0 && inside.bottom == 0);
BOOL isInvalidLocation = ((outside.left == -32000 && outside.top == -32000) || // Win2k && WinXP
(outside.left == 32000 && outside.top == 32000) || // Win95 && Win98
(outside.left == 3000 && outside.top == 3000)); // Win95 && Win98
// the bounds correspond to iconic state
if (isZeroClientArea && isInvalidLocation)
{
return FALSE;
}
return TRUE;
}
void AwtWindow::_SetIconImagesData(void * param)
{
JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
SetIconImagesDataStruct* s = (SetIconImagesDataStruct*)param;
jobject self = s->window;
jintArray iconRaster = s->iconRaster;
jintArray smallIconRaster = s->smallIconRaster;
AwtWindow *window = NULL;
PDATA pData;
JNI_CHECK_PEER_GOTO(self, ret);
// ok to pass null raster: default AWT icon
window = (AwtWindow*)pData;
if (::IsWindow(window->GetHWnd()))
{
window->SetIconData(env, iconRaster, s->w, s->h, smallIconRaster, s->smw, s->smh);
}
ret:
env->DeleteGlobalRef(self);
env->DeleteGlobalRef(iconRaster);
env->DeleteGlobalRef(smallIconRaster);
delete s;
}
void AwtWindow::_SetMinSize(void* param)
{
JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
SizeStruct *ss = (SizeStruct *)param;
jobject self = ss->window;
jint w = ss->w;
jint h = ss->h;
//Perform size setting
AwtWindow *window = NULL;
PDATA pData;
JNI_CHECK_PEER_GOTO(self, ret);
window = (AwtWindow *)pData;
window->m_minSize.x = w;
window->m_minSize.y = h;
ret:
env->DeleteGlobalRef(self);
delete ss;
}
jint AwtWindow::_GetScreenImOn(void *param)
{
JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
jobject self = (jobject)param;
// It's entirely possible that our native resources have been destroyed
// before our java peer - if we're dispose()d, for instance.
// Alert caller w/ IllegalComponentStateException.
if (self == NULL) {
JNU_ThrowByName(env, "java/awt/IllegalComponentStateException",
"Peer null in JNI");
return 0;
}
PDATA pData = JNI_GET_PDATA(self);
if (pData == NULL) {
JNU_ThrowByName(env, "java/awt/IllegalComponentStateException",
"Native resources unavailable");
env->DeleteGlobalRef(self);
return 0;
}
jint result = 0;
AwtWindow *w = (AwtWindow *)pData;
if (::IsWindow(w->GetHWnd()))
{
result = (jint)w->GetScreenImOn();
}
env->DeleteGlobalRef(self);
return result;
}
void AwtWindow::_SetFocusableWindow(void *param)
{
JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
SetFocusableWindowStruct *sfws = (SetFocusableWindowStruct *)param;
jobject self = sfws->window;
jboolean isFocusableWindow = sfws->isFocusableWindow;
AwtWindow *window = NULL;
PDATA pData;
JNI_CHECK_PEER_GOTO(self, ret);
window = (AwtWindow *)pData;
window->m_isFocusableWindow = isFocusableWindow;
// A simple window is permanently set to WS_EX_NOACTIVATE
if (!window->IsSimpleWindow()) {
if (!window->m_isFocusableWindow) {
LONG isPopup = window->GetStyle() & WS_POPUP;
window->SetStyleEx(window->GetStyleEx() | (isPopup ? 0 : WS_EX_APPWINDOW) | WS_EX_NOACTIVATE);
} else {
window->SetStyleEx(window->GetStyleEx() & ~WS_EX_APPWINDOW & ~WS_EX_NOACTIVATE);
}
}
ret:
env->DeleteGlobalRef(self);
delete sfws;
}
void AwtWindow::_ModalDisable(void *param)
{
JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
ModalDisableStruct *mds = (ModalDisableStruct *)param;
jobject self = mds->window;
HWND blockerHWnd = (HWND)mds->blockerHWnd;
AwtWindow *window = NULL;
HWND windowHWnd = 0;
JNI_CHECK_NULL_GOTO(self, "peer", ret);
PDATA pData = JNI_GET_PDATA(self);
if (pData == NULL) {
env->DeleteGlobalRef(self);
delete mds;
return;
}
window = (AwtWindow *)pData;
windowHWnd = window->GetHWnd();
if (::IsWindow(windowHWnd)) {
AwtWindow::SetAndActivateModalBlocker(windowHWnd, blockerHWnd);
}
ret:
env->DeleteGlobalRef(self);
delete mds;
}
void AwtWindow::_ModalEnable(void *param)
{
JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
jobject self = (jobject)param;
AwtWindow *window = NULL;
HWND windowHWnd = 0;
JNI_CHECK_NULL_GOTO(self, "peer", ret);
PDATA pData = JNI_GET_PDATA(self);
if (pData == NULL) {
env->DeleteGlobalRef(self);
return;
}
window = (AwtWindow *)pData;
windowHWnd = window->GetHWnd();
if (::IsWindow(windowHWnd)) {
AwtWindow::SetModalBlocker(windowHWnd, NULL);
}
ret:
env->DeleteGlobalRef(self);
}
void AwtWindow::_SetOpacity(void* param)
{
JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
OpacityStruct *os = (OpacityStruct *)param;
jobject self = os->window;
BYTE iOpacity = (BYTE)os->iOpacity;
PDATA pData;
JNI_CHECK_PEER_GOTO(self, ret);
AwtWindow *window = (AwtWindow *)pData;
window->SetTranslucency(iOpacity, window->isOpaque());
ret:
env->DeleteGlobalRef(self);
delete os;
}
void AwtWindow::_SetOpaque(void* param)
{
JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
OpaqueStruct *os = (OpaqueStruct *)param;
jobject self = os->window;
BOOL isOpaque = (BOOL)os->isOpaque;
PDATA pData;
JNI_CHECK_PEER_GOTO(self, ret);
AwtWindow *window = (AwtWindow *)pData;
window->SetTranslucency(window->getOpacity(), isOpaque);
ret:
env->DeleteGlobalRef(self);
delete os;
}
void AwtWindow::_UpdateWindow(void* param)
{
JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
UpdateWindowStruct *uws = (UpdateWindowStruct *)param;
jobject self = uws->window;
jintArray data = uws->data;
PDATA pData;
JNI_CHECK_PEER_GOTO(self, ret);
AwtWindow *window = (AwtWindow *)pData;
window->UpdateWindow(env, data, (int)uws->width, (int)uws->height,
uws->hBitmap);
ret:
env->DeleteGlobalRef(self);
if (data != NULL) {
env->DeleteGlobalRef(data);
}
delete uws;
}
void AwtWindow::_SetFullScreenExclusiveModeState(void *param)
{
JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
SetFullScreenExclusiveModeStateStruct * data =
(SetFullScreenExclusiveModeStateStruct*)param;
jobject self = data->window;
jboolean state = data->isFSEMState;
PDATA pData;
JNI_CHECK_PEER_GOTO(self, ret);
AwtWindow *window = (AwtWindow *)pData;
window->setFullScreenExclusiveModeState(state != 0);
ret:
env->DeleteGlobalRef(self);
delete data;
}
extern "C" {
/*
* Class: java_awt_Window
* Method: initIDs
* Signature: ()V
*/
JNIEXPORT void JNICALL
Java_java_awt_Window_initIDs(JNIEnv *env, jclass cls)
{
TRY;
AwtWindow::warningStringID =
env->GetFieldID(cls, "warningString", "Ljava/lang/String;");
AwtWindow::locationByPlatformID =
env->GetFieldID(cls, "locationByPlatform", "Z");
AwtWindow::securityWarningWidthID =
env->GetFieldID(cls, "securityWarningWidth", "I");
AwtWindow::securityWarningHeightID =
env->GetFieldID(cls, "securityWarningHeight", "I");
AwtWindow::getWarningStringMID =
env->GetMethodID(cls, "getWarningString", "()Ljava/lang/String;");
AwtWindow::autoRequestFocusID =
env->GetFieldID(cls, "autoRequestFocus", "Z");
AwtWindow::calculateSecurityWarningPositionMID =
env->GetMethodID(cls, "calculateSecurityWarningPosition", "(DDDD)Ljava/awt/geom/Point2D;");
jclass windowTypeClass = env->FindClass("java/awt/Window$Type");
AwtWindow::windowTypeNameMID =
env->GetMethodID(windowTypeClass, "name", "()Ljava/lang/String;");
env->DeleteLocalRef(windowTypeClass);
CATCH_BAD_ALLOC;
}
} /* extern "C" */
/************************************************************************
* WindowPeer native methods
*/
extern "C" {
/*
* Class: sun_awt_windows_WWindowPeer
* Method: initIDs
* Signature: ()V
*/
JNIEXPORT void JNICALL
Java_sun_awt_windows_WWindowPeer_initIDs(JNIEnv *env, jclass cls)
{
TRY;
AwtWindow::sysXID = env->GetFieldID(cls, "sysX", "I");
AwtWindow::sysYID = env->GetFieldID(cls, "sysY", "I");
AwtWindow::sysWID = env->GetFieldID(cls, "sysW", "I");
AwtWindow::sysHID = env->GetFieldID(cls, "sysH", "I");
AwtWindow::windowTypeID = env->GetFieldID(cls, "windowType",
"Ljava/awt/Window$Type;");
CATCH_BAD_ALLOC;
}
/*
* Class: sun_awt_windows_WWindowPeer
* Method: toFront
* Signature: ()V
*/
JNIEXPORT void JNICALL
Java_sun_awt_windows_WWindowPeer__1toFront(JNIEnv *env, jobject self)
{
TRY;
AwtToolkit::GetInstance().SyncCall(AwtWindow::_ToFront,
env->NewGlobalRef(self));
// global ref is deleted in _ToFront()
CATCH_BAD_ALLOC;
}
/*
* Class: sun_awt_windows_WWindowPeer
* Method: toBack
* Signature: ()V
*/
JNIEXPORT void JNICALL
Java_sun_awt_windows_WWindowPeer_toBack(JNIEnv *env, jobject self)
{
TRY;
AwtToolkit::GetInstance().SyncCall(AwtWindow::_ToBack,
env->NewGlobalRef(self));
// global ref is deleted in _ToBack()
CATCH_BAD_ALLOC;
}
/*
* Class: sun_awt_windows_WWindowPeer
* Method: setAlwaysOnTop
* Signature: (Z)V
*/
JNIEXPORT void JNICALL
Java_sun_awt_windows_WWindowPeer_setAlwaysOnTopNative(JNIEnv *env, jobject self,
jboolean value)
{
TRY;
SetAlwaysOnTopStruct *sas = new SetAlwaysOnTopStruct;
sas->window = env->NewGlobalRef(self);
sas->value = value;
AwtToolkit::GetInstance().SyncCall(AwtWindow::_SetAlwaysOnTop, sas);
// global ref and sas are deleted in _SetAlwaysOnTop
CATCH_BAD_ALLOC;
}
/*
* Class: sun_awt_windows_WWindowPeer
* Method: _setTitle
* Signature: (Ljava/lang/String;)V
*/
JNIEXPORT void JNICALL
Java_sun_awt_windows_WWindowPeer__1setTitle(JNIEnv *env, jobject self,
jstring title)
{
TRY;
SetTitleStruct *sts = new SetTitleStruct;
sts->window = env->NewGlobalRef(self);
sts->title = (jstring)env->NewGlobalRef(title);
AwtToolkit::GetInstance().SyncCall(AwtWindow::_SetTitle, sts);
/// global refs and sts are deleted in _SetTitle()
CATCH_BAD_ALLOC;
}
/*
* Class: sun_awt_windows_WWindowPeer
* Method: _setResizable
* Signature: (Z)V
*/
JNIEXPORT void JNICALL
Java_sun_awt_windows_WWindowPeer__1setResizable(JNIEnv *env, jobject self,
jboolean resizable)
{
TRY;
SetResizableStruct *srs = new SetResizableStruct;
srs->window = env->NewGlobalRef(self);
srs->resizable = resizable;
AwtToolkit::GetInstance().SyncCall(AwtWindow::_SetResizable, srs);
// global ref and srs are deleted in _SetResizable
CATCH_BAD_ALLOC;
}
/*
* Class: sun_awt_windows_WWindowPeer
* Method: create
* Signature: (Lsun/awt/windows/WComponentPeer;)V
*/
JNIEXPORT void JNICALL
Java_sun_awt_windows_WWindowPeer_createAwtWindow(JNIEnv *env, jobject self,
jobject parent)
{
TRY;
PDATA pData;
// JNI_CHECK_PEER_RETURN(parent);
AwtToolkit::CreateComponent(self, parent,
(AwtToolkit::ComponentFactory)
AwtWindow::Create);
JNI_CHECK_PEER_CREATION_RETURN(self);
CATCH_BAD_ALLOC;
}
/*
* Class: sun_awt_windows_WWindowPeer
* Method: updateInsets
* Signature: (Ljava/awt/Insets;)V
*/
JNIEXPORT void JNICALL
Java_sun_awt_windows_WWindowPeer_updateInsets(JNIEnv *env, jobject self,
jobject insets)
{
TRY;
UpdateInsetsStruct *uis = new UpdateInsetsStruct;
uis->window = env->NewGlobalRef(self);
uis->insets = env->NewGlobalRef(insets);
AwtToolkit::GetInstance().SyncCall(AwtWindow::_UpdateInsets, uis);
// global refs and uis are deleted in _UpdateInsets()
CATCH_BAD_ALLOC;
}
/*
* Class: sun_awt_windows_WWindowPeer
* Method: reshapeFrame
* Signature: (IIII)V
*/
JNIEXPORT void JNICALL
Java_sun_awt_windows_WWindowPeer_reshapeFrame(JNIEnv *env, jobject self,
jint x, jint y, jint w, jint h)
{
TRY;
ReshapeFrameStruct *rfs = new ReshapeFrameStruct;
rfs->frame = env->NewGlobalRef(self);
rfs->x = x;
rfs->y = y;
rfs->w = w;
rfs->h = h;
AwtToolkit::GetInstance().SyncCall(AwtWindow::_ReshapeFrame, rfs);
// global ref and rfs are deleted in _ReshapeFrame()
CATCH_BAD_ALLOC;
}
/*
* Class: sun_awt_windows_WWindowPeer
* Method: getSysMinWidth
* Signature: ()I
*/
JNIEXPORT jint JNICALL
Java_sun_awt_windows_WWindowPeer_getSysMinWidth(JNIEnv *env, jclass self)
{
TRY;
return ::GetSystemMetrics(SM_CXMIN);
CATCH_BAD_ALLOC_RET(0);
}
/*
* Class: sun_awt_windows_WWindowPeer
* Method: getSysMinHeight
* Signature: ()I
*/
JNIEXPORT jint JNICALL
Java_sun_awt_windows_WWindowPeer_getSysMinHeight(JNIEnv *env, jclass self)
{
TRY;
return ::GetSystemMetrics(SM_CYMIN);
CATCH_BAD_ALLOC_RET(0);
}
/*
* Class: sun_awt_windows_WWindowPeer
* Method: getSysIconHeight
* Signature: ()I
*/
JNIEXPORT jint JNICALL
Java_sun_awt_windows_WWindowPeer_getSysIconHeight(JNIEnv *env, jclass self)
{
TRY;
return ::GetSystemMetrics(SM_CYICON);
CATCH_BAD_ALLOC_RET(0);
}
/*
* Class: sun_awt_windows_WWindowPeer
* Method: getSysIconWidth
* Signature: ()I
*/
JNIEXPORT jint JNICALL
Java_sun_awt_windows_WWindowPeer_getSysIconWidth(JNIEnv *env, jclass self)
{
TRY;
return ::GetSystemMetrics(SM_CXICON);
CATCH_BAD_ALLOC_RET(0);
}
/*
* Class: sun_awt_windows_WWindowPeer
* Method: getSysSmIconHeight
* Signature: ()I
*/
JNIEXPORT jint JNICALL
Java_sun_awt_windows_WWindowPeer_getSysSmIconHeight(JNIEnv *env, jclass self)
{
TRY;
return ::GetSystemMetrics(SM_CYSMICON);
CATCH_BAD_ALLOC_RET(0);
}
/*
* Class: sun_awt_windows_WWindowPeer
* Method: getSysSmIconWidth
* Signature: ()I
*/
JNIEXPORT jint JNICALL
Java_sun_awt_windows_WWindowPeer_getSysSmIconWidth(JNIEnv *env, jclass self)
{
TRY;
return ::GetSystemMetrics(SM_CXSMICON);
CATCH_BAD_ALLOC_RET(0);
}
/*
* Class: sun_awt_windows_WWindowPeer
* Method: setIconImagesData
* Signature: ([I)V
*/
JNIEXPORT void JNICALL
Java_sun_awt_windows_WWindowPeer_setIconImagesData(JNIEnv *env, jobject self,
jintArray iconRaster, jint w, jint h,
jintArray smallIconRaster, jint smw, jint smh)
{
TRY;
SetIconImagesDataStruct *sims = new SetIconImagesDataStruct;
sims->window = env->NewGlobalRef(self);
sims->iconRaster = (jintArray)env->NewGlobalRef(iconRaster);
sims->w = w;
sims->h = h;
sims->smallIconRaster = (jintArray)env->NewGlobalRef(smallIconRaster);
sims->smw = smw;
sims->smh = smh;
AwtToolkit::GetInstance().SyncCall(AwtWindow::_SetIconImagesData, sims);
// global refs and sims are deleted in _SetIconImagesData()
CATCH_BAD_ALLOC;
}
/*
* Class: sun_awt_windows_WWindowPeer
* Method: setMinSize
* Signature: (Lsun/awt/windows/WWindowPeer;)V
*/
JNIEXPORT void JNICALL
Java_sun_awt_windows_WWindowPeer_setMinSize(JNIEnv *env, jobject self,
jint w, jint h)
{
TRY;
SizeStruct *ss = new SizeStruct;
ss->window = env->NewGlobalRef(self);
ss->w = w;
ss->h = h;
AwtToolkit::GetInstance().SyncCall(AwtWindow::_SetMinSize, ss);
// global refs and mds are deleted in _SetMinSize
CATCH_BAD_ALLOC;
}
/*
* Class: sun_awt_windows_WWindowPeer
* Method: getScreenImOn
* Signature: ()I
*/
JNIEXPORT jint JNICALL
Java_sun_awt_windows_WWindowPeer_getScreenImOn(JNIEnv *env, jobject self)
{
TRY;
return static_cast<jint>(reinterpret_cast(AwtToolkit::GetInstance().SyncCall(
(void *(*)(void *))AwtWindow::_GetScreenImOn,
env->NewGlobalRef(self))));
// global ref is deleted in _GetScreenImOn()
CATCH_BAD_ALLOC_RET(-1);
}
/*
* Class: sun_awt_windows_WWindowPeer
* Method: setFullScreenExclusiveModeState
* Signature: (Z)V
*/
JNIEXPORT void JNICALL
Java_sun_awt_windows_WWindowPeer_setFullScreenExclusiveModeState(JNIEnv *env,
jobject self, jboolean state)
{
TRY;
SetFullScreenExclusiveModeStateStruct *data =
new SetFullScreenExclusiveModeStateStruct;
data->window = env->NewGlobalRef(self);
data->isFSEMState = state;
AwtToolkit::GetInstance().SyncCall(
AwtWindow::_SetFullScreenExclusiveModeState, data);
// global ref and data are deleted in the invoked method
CATCH_BAD_ALLOC;
}
/*
* Class: sun_awt_windows_WWindowPeer
* Method: modalDisable
* Signature: (J)V
*/
JNIEXPORT void JNICALL
Java_sun_awt_windows_WWindowPeer_modalDisable(JNIEnv *env, jobject self,
jobject blocker, jlong blockerHWnd)
{
TRY;
ModalDisableStruct *mds = new ModalDisableStruct;
mds->window = env->NewGlobalRef(self);
mds->blockerHWnd = blockerHWnd;
AwtToolkit::GetInstance().SyncCall(AwtWindow::_ModalDisable, mds);
// global ref and mds are deleted in _ModalDisable
CATCH_BAD_ALLOC;
}
/*
* Class: sun_awt_windows_WWindowPeer
* Method: modalEnable
* Signature: ()V
*/
JNIEXPORT void JNICALL
Java_sun_awt_windows_WWindowPeer_modalEnable(JNIEnv *env, jobject self, jobject blocker)
{
TRY;
AwtToolkit::GetInstance().SyncCall(AwtWindow::_ModalEnable,
env->NewGlobalRef(self));
// global ref is deleted in _ModalEnable
CATCH_BAD_ALLOC;
}
/*
* Class: sun_awt_windows_WWindowPeer
* Method: setFocusableWindow
* Signature: (Z)V
*/
JNIEXPORT void JNICALL
Java_sun_awt_windows_WWindowPeer_setFocusableWindow(JNIEnv *env, jobject self, jboolean isFocusableWindow)
{
TRY;
SetFocusableWindowStruct *sfws = new SetFocusableWindowStruct;
sfws->window = env->NewGlobalRef(self);
sfws->isFocusableWindow = isFocusableWindow;
AwtToolkit::GetInstance().SyncCall(AwtWindow::_SetFocusableWindow, sfws);
// global ref and sfws are deleted in _SetFocusableWindow()
CATCH_BAD_ALLOC;
}
JNIEXPORT void JNICALL
Java_sun_awt_windows_WWindowPeer_nativeGrab(JNIEnv *env, jobject self)
{
TRY;
AwtToolkit::GetInstance().SyncCall(AwtWindow::_Grab, env->NewGlobalRef(self));
// global ref is deleted in _Grab()
CATCH_BAD_ALLOC;
}
JNIEXPORT void JNICALL
Java_sun_awt_windows_WWindowPeer_nativeUngrab(JNIEnv *env, jobject self)
{
TRY;
AwtToolkit::GetInstance().SyncCall(AwtWindow::_Ungrab, env->NewGlobalRef(self));
// global ref is deleted in _Ungrab()
CATCH_BAD_ALLOC;
}
/*
* Class: sun_awt_windows_WWindowPeer
* Method: setOpacity
* Signature: (I)V
*/
JNIEXPORT void JNICALL
Java_sun_awt_windows_WWindowPeer_setOpacity(JNIEnv *env, jobject self,
jint iOpacity)
{
TRY;
OpacityStruct *os = new OpacityStruct;
os->window = env->NewGlobalRef(self);
os->iOpacity = iOpacity;
AwtToolkit::GetInstance().SyncCall(AwtWindow::_SetOpacity, os);
// global refs and mds are deleted in _SetMinSize
CATCH_BAD_ALLOC;
}
/*
* Class: sun_awt_windows_WWindowPeer
* Method: setOpaqueImpl
* Signature: (Z)V
*/
JNIEXPORT void JNICALL
Java_sun_awt_windows_WWindowPeer_setOpaqueImpl(JNIEnv *env, jobject self,
jboolean isOpaque)
{
TRY;
OpaqueStruct *os = new OpaqueStruct;
os->window = env->NewGlobalRef(self);
os->isOpaque = isOpaque;
AwtToolkit::GetInstance().SyncCall(AwtWindow::_SetOpaque, os);
// global refs and mds are deleted in _SetMinSize
CATCH_BAD_ALLOC;
}
/*
* Class: sun_awt_windows_WWindowPeer
* Method: updateWindowImpl
* Signature: ([III)V
*/
JNIEXPORT void JNICALL
Java_sun_awt_windows_WWindowPeer_updateWindowImpl(JNIEnv *env, jobject self,
jintArray data,
jint width, jint height)
{
TRY;
UpdateWindowStruct *uws = new UpdateWindowStruct;
uws->window = env->NewGlobalRef(self);
uws->data = (jintArray)env->NewGlobalRef(data);
uws->hBitmap = NULL;
uws->width = width;
uws->height = height;
AwtToolkit::GetInstance().InvokeFunction(AwtWindow::_UpdateWindow, uws);
// global refs and mds are deleted in _UpdateWindow
CATCH_BAD_ALLOC;
}
/**
* This method is called from the WGL pipeline when it needs to update
* the layered window WindowPeer's C++ level object.
*/
void AwtWindow_UpdateWindow(JNIEnv *env, jobject peer,
jint width, jint height, HBITMAP hBitmap)
{
TRY;
UpdateWindowStruct *uws = new UpdateWindowStruct;
uws->window = env->NewGlobalRef(peer);
uws->data = NULL;
uws->hBitmap = hBitmap;
uws->width = width;
uws->height = height;
AwtToolkit::GetInstance().InvokeFunction(AwtWindow::_UpdateWindow, uws);
// global refs and mds are deleted in _UpdateWindow
CATCH_BAD_ALLOC;
}
/*
* Class: sun_awt_windows_WComponentPeer
* Method: requestFocus
* Signature: (Z)Z
*/
JNIEXPORT jboolean JNICALL Java_sun_awt_windows_WWindowPeer_requestWindowFocus
(JNIEnv *env, jobject self, jboolean isMouseEventCause)
{
TRY;
jobject selfGlobalRef = env->NewGlobalRef(self);
RequestWindowFocusStruct *rfs = new RequestWindowFocusStruct;
rfs->component = selfGlobalRef;
rfs->isMouseEventCause = isMouseEventCause;
return (jboolean)AwtToolkit::GetInstance().SyncCall(
(void*(*)(void*))AwtWindow::_RequestWindowFocus, rfs);
// global refs and rfs are deleted in _RequestWindowFocus
CATCH_BAD_ALLOC_RET(JNI_FALSE);
}
/*
* Class: sun_awt_windows_WWindowPeer
* Method: repositionSecurityWarning
* Signature: ()V
*/
JNIEXPORT void JNICALL
Java_sun_awt_windows_WWindowPeer_repositionSecurityWarning(JNIEnv *env,
jobject self)
{
TRY;
RepositionSecurityWarningStruct *rsws =
new RepositionSecurityWarningStruct;
rsws->window = env->NewGlobalRef(self);
AwtToolkit::GetInstance().InvokeFunction(
AwtWindow::_RepositionSecurityWarning, rsws);
// global refs and mds are deleted in _RepositionSecurityWarning
CATCH_BAD_ALLOC;
}
} /* extern "C" */
Other Java examples (source code examples)
Here is a short list of links related to this Java awt_Window.cpp source code file:
|