annotate src/windows/native/sun/windows/awt_Frame.cpp @ 4084:6303d3a93040

7034291: Regression : Preedit String on active client is committed into unexpected component Reviewed-by: art, naoto
author dcherepanov
date Fri, 29 Apr 2011 16:02:05 +0400
parents 43be19b7c945
children 997f464f8446
rev   line source
duke@0 1 /*
ohair@3909 2 * Copyright (c) 1996, 2011, Oracle and/or its affiliates. All rights reserved.
duke@0 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
duke@0 4 *
duke@0 5 * This code is free software; you can redistribute it and/or modify it
duke@0 6 * under the terms of the GNU General Public License version 2 only, as
ohair@2362 7 * published by the Free Software Foundation. Oracle designates this
duke@0 8 * particular file as subject to the "Classpath" exception as provided
ohair@2362 9 * by Oracle in the LICENSE file that accompanied this code.
duke@0 10 *
duke@0 11 * This code is distributed in the hope that it will be useful, but WITHOUT
duke@0 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
duke@0 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
duke@0 14 * version 2 for more details (a copy is included in the LICENSE file that
duke@0 15 * accompanied this code).
duke@0 16 *
duke@0 17 * You should have received a copy of the GNU General Public License version
duke@0 18 * 2 along with this work; if not, write to the Free Software Foundation,
duke@0 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
duke@0 20 *
ohair@2362 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
ohair@2362 22 * or visit www.oracle.com if you need additional information or have any
ohair@2362 23 * questions.
duke@0 24 */
duke@0 25
duke@0 26 #include "awt_Toolkit.h"
duke@0 27 #include "awt_Frame.h"
duke@0 28 #include "awt_MenuBar.h"
duke@0 29 #include "awt_Dialog.h"
duke@0 30 #include "awt_IconCursor.h"
duke@0 31 #include "awt_Win32GraphicsDevice.h"
duke@0 32 #include "ComCtl32Util.h"
duke@0 33
duke@0 34 #include <windowsx.h>
duke@0 35
duke@0 36 #include <java_lang_Integer.h>
duke@0 37 #include <sun_awt_EmbeddedFrame.h>
duke@0 38 #include <sun_awt_windows_WEmbeddedFrame.h>
duke@0 39 #include <sun_awt_windows_WEmbeddedFramePeer.h>
duke@0 40
duke@0 41
duke@0 42 /* IMPORTANT! Read the README.JNI file for notes on JNI converted AWT code.
duke@0 43 */
duke@0 44
duke@0 45 /***********************************************************************/
duke@0 46 // Struct for _SetState() method
duke@0 47 struct SetStateStruct {
duke@0 48 jobject frame;
duke@0 49 jint state;
duke@0 50 };
duke@0 51 // Struct for _SetMaximizedBounds() method
duke@0 52 struct SetMaximizedBoundsStruct {
duke@0 53 jobject frame;
duke@0 54 jint x, y;
duke@0 55 jint width, height;
duke@0 56 };
duke@0 57 // Struct for _SetMenuBar() method
duke@0 58 struct SetMenuBarStruct {
duke@0 59 jobject frame;
duke@0 60 jobject menubar;
duke@0 61 };
duke@0 62
duke@0 63 // Struct for _SetIMMOption() method
duke@0 64 struct SetIMMOptionStruct {
duke@0 65 jobject frame;
duke@0 66 jstring option;
duke@0 67 };
duke@0 68 // Struct for _SynthesizeWmActivate() method
duke@0 69 struct SynthesizeWmActivateStruct {
duke@0 70 jobject frame;
duke@0 71 jboolean doActivate;
duke@0 72 };
duke@0 73 // Struct for _NotifyModalBlocked() method
duke@0 74 struct NotifyModalBlockedStruct {
duke@0 75 jobject frame;
duke@0 76 jobject peer;
duke@0 77 jobject blockerPeer;
duke@0 78 jboolean blocked;
duke@0 79 };
duke@0 80 // Information about thread containing modal blocked embedded frames
duke@0 81 struct BlockedThreadStruct {
duke@0 82 int framesCount;
duke@0 83 HHOOK mouseHook;
duke@0 84 HHOOK modalHook;
duke@0 85 };
duke@0 86 /************************************************************************
duke@0 87 * AwtFrame fields
duke@0 88 */
duke@0 89
duke@0 90 jfieldID AwtFrame::handleID;
dcherepanov@1047 91
duke@0 92 jfieldID AwtFrame::undecoratedID;
dcherepanov@1047 93 jmethodID AwtFrame::getExtendedStateMID;
dcherepanov@1047 94 jmethodID AwtFrame::setExtendedStateMID;
duke@0 95
duke@0 96 jmethodID AwtFrame::activateEmbeddingTopLevelMID;
duke@0 97
duke@0 98 Hashtable AwtFrame::sm_BlockedThreads("AWTBlockedThreads");
duke@0 99
duke@0 100 /************************************************************************
duke@0 101 * AwtFrame methods
duke@0 102 */
duke@0 103
duke@0 104 AwtFrame::AwtFrame() {
duke@0 105 m_parentWnd = NULL;
duke@0 106 menuBar = NULL;
duke@0 107 m_isEmbedded = FALSE;
duke@0 108 m_ignoreWmSize = FALSE;
duke@0 109 m_isMenuDropped = FALSE;
duke@0 110 m_isInputMethodWindow = FALSE;
duke@0 111 m_isUndecorated = FALSE;
dcherepanov@4084 112 m_imeTargetComponent = NULL;
duke@0 113 m_actualFocusedWindow = NULL;
duke@0 114 m_iconic = FALSE;
duke@0 115 m_zoomed = FALSE;
duke@0 116 m_maxBoundsSet = FALSE;
duke@0 117 m_forceResetZoomed = FALSE;
duke@0 118
duke@0 119 isInManualMoveOrSize = FALSE;
duke@0 120 grabbedHitTest = 0;
duke@0 121 }
duke@0 122
duke@0 123 AwtFrame::~AwtFrame()
duke@0 124 {
duke@0 125 }
duke@0 126
duke@0 127 void AwtFrame::Dispose()
duke@0 128 {
duke@0 129 AwtWindow::Dispose();
duke@0 130 }
duke@0 131
duke@0 132 LPCTSTR AwtFrame::GetClassName() {
duke@0 133 return AWT_FRAME_WINDOW_CLASS_NAME;
duke@0 134 }
duke@0 135
duke@0 136 /*
duke@0 137 * Create a new AwtFrame object and window.
duke@0 138 */
duke@0 139 AwtFrame* AwtFrame::Create(jobject self, jobject parent)
duke@0 140 {
duke@0 141 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
duke@0 142 if (env->EnsureLocalCapacity(1) < 0) {
duke@0 143 return NULL;
duke@0 144 }
duke@0 145
duke@0 146 PDATA pData;
duke@0 147 HWND hwndParent = NULL;
duke@0 148 AwtFrame* frame;
duke@0 149 jclass cls = NULL;
duke@0 150 jclass inputMethodWindowCls = NULL;
duke@0 151 jobject target = NULL;
duke@0 152
duke@0 153 try {
duke@0 154 target = env->GetObjectField(self, AwtObject::targetID);
duke@0 155 JNI_CHECK_NULL_GOTO(target, "target", done);
duke@0 156
duke@0 157 if (parent != NULL) {
duke@0 158 JNI_CHECK_PEER_GOTO(parent, done);
duke@0 159 {
duke@0 160 AwtFrame* parent = (AwtFrame *)pData;
duke@0 161 hwndParent = parent->GetHWnd();
duke@0 162 }
duke@0 163 }
duke@0 164
duke@0 165 frame = new AwtFrame();
duke@0 166
duke@0 167 {
duke@0 168 /*
duke@0 169 * A variation on Netscape's hack for embedded frames: the client
duke@0 170 * area of the browser is a Java Frame for parenting purposes, but
duke@0 171 * really a Windows child window
duke@0 172 */
duke@0 173 cls = env->FindClass("sun/awt/EmbeddedFrame");
duke@0 174 if (cls == NULL) {
duke@0 175 return NULL;
duke@0 176 }
duke@0 177 INT_PTR handle;
duke@0 178 jboolean isEmbeddedInstance = env->IsInstanceOf(target, cls);
duke@0 179 jboolean isEmbedded = FALSE;
duke@0 180
duke@0 181 if (isEmbeddedInstance) {
duke@0 182 handle = static_cast<INT_PTR>(env->GetLongField(target, AwtFrame::handleID));
duke@0 183 if (handle != 0) {
duke@0 184 isEmbedded = TRUE;
duke@0 185 }
duke@0 186 }
duke@0 187 frame->m_isEmbedded = isEmbedded;
duke@0 188
duke@0 189 if (isEmbedded) {
duke@0 190 hwndParent = (HWND)handle;
duke@0 191 RECT rect;
duke@0 192 ::GetClientRect(hwndParent, &rect);
duke@0 193 //Fix for 6328675: SWT_AWT.new_Frame doesn't occupy client area under JDK6
duke@0 194 frame->m_isUndecorated = true;
duke@0 195 /*
duke@0 196 * Fix for BugTraq ID 4337754.
duke@0 197 * Initialize m_peerObject before the first call
duke@0 198 * to AwtFrame::GetClassName().
duke@0 199 */
duke@0 200 frame->m_peerObject = env->NewGlobalRef(self);
duke@0 201 frame->RegisterClass();
duke@0 202 DWORD exStyle = WS_EX_NOPARENTNOTIFY;
duke@0 203
duke@0 204 if (GetRTL()) {
duke@0 205 exStyle |= WS_EX_RIGHT | WS_EX_LEFTSCROLLBAR;
duke@0 206 if (GetRTLReadingOrder())
duke@0 207 exStyle |= WS_EX_RTLREADING;
duke@0 208 }
duke@0 209
duke@0 210 frame->m_hwnd = ::CreateWindowEx(exStyle,
duke@0 211 frame->GetClassName(), TEXT(""),
duke@0 212 WS_CHILD | WS_CLIPCHILDREN,
duke@0 213 0, 0,
duke@0 214 rect.right, rect.bottom,
duke@0 215 hwndParent, NULL,
duke@0 216 AwtToolkit::GetInstance().GetModuleHandle(),
duke@0 217 NULL);
duke@0 218 frame->LinkObjects(env, self);
duke@0 219 frame->SubclassHWND();
duke@0 220
duke@0 221 // Update target's dimensions to reflect this embedded window.
duke@0 222 ::GetClientRect(frame->m_hwnd, &rect);
son@82 223 ::MapWindowPoints(frame->m_hwnd, hwndParent, (LPPOINT)&rect, 2);
duke@0 224
duke@0 225 env->SetIntField(target, AwtComponent::xID, rect.left);
duke@0 226 env->SetIntField(target, AwtComponent::yID, rect.top);
duke@0 227 env->SetIntField(target, AwtComponent::widthID,
duke@0 228 rect.right-rect.left);
duke@0 229 env->SetIntField(target, AwtComponent::heightID,
duke@0 230 rect.bottom-rect.top);
duke@0 231 frame->InitPeerGraphicsConfig(env, self);
son@82 232 AwtToolkit::GetInstance().RegisterEmbedderProcessId(hwndParent);
duke@0 233 } else {
dcherepanov@1047 234 jint state = env->CallIntMethod(self, AwtFrame::getExtendedStateMID);
duke@0 235 DWORD exStyle;
duke@0 236 DWORD style;
duke@0 237
duke@0 238 // for input method windows, use minimal decorations
duke@0 239 inputMethodWindowCls = env->FindClass("sun/awt/im/InputMethodWindow");
duke@0 240 if ((inputMethodWindowCls != NULL) && env->IsInstanceOf(target, inputMethodWindowCls)) {
duke@0 241 //for below-the-spot composition window, use no decoration
duke@0 242 if (env->GetBooleanField(target, AwtFrame::undecoratedID) == JNI_TRUE){
duke@0 243 exStyle = 0;
duke@0 244 style = WS_POPUP|WS_CLIPCHILDREN;
duke@0 245 frame->m_isUndecorated = TRUE;
duke@0 246 } else {
duke@0 247 exStyle = WS_EX_PALETTEWINDOW;
duke@0 248 style = WS_CLIPCHILDREN;
duke@0 249 }
duke@0 250 frame->m_isInputMethodWindow = TRUE;
duke@0 251 } else if (env->GetBooleanField(target, AwtFrame::undecoratedID) == JNI_TRUE) {
duke@0 252 exStyle = 0;
duke@0 253 style = WS_POPUP | WS_SYSMENU | WS_CLIPCHILDREN |
duke@0 254 WS_MAXIMIZEBOX | WS_MINIMIZEBOX;
duke@0 255 if (state & java_awt_Frame_ICONIFIED) {
duke@0 256 frame->setIconic(TRUE);
duke@0 257 }
duke@0 258 frame->m_isUndecorated = TRUE;
duke@0 259 } else {
duke@0 260 exStyle = WS_EX_WINDOWEDGE;
duke@0 261 style = WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN;
duke@0 262 if (state & java_awt_Frame_ICONIFIED) {
duke@0 263 frame->setIconic(TRUE);
duke@0 264 }
duke@0 265 }
duke@0 266
duke@0 267 if (GetRTL()) {
duke@0 268 exStyle |= WS_EX_RIGHT | WS_EX_LEFTSCROLLBAR;
duke@0 269 if (GetRTLReadingOrder())
duke@0 270 exStyle |= WS_EX_RTLREADING;
duke@0 271 }
duke@0 272
duke@0 273 jint x = env->GetIntField(target, AwtComponent::xID);
duke@0 274 jint y = env->GetIntField(target, AwtComponent::yID);
duke@0 275 jint width = env->GetIntField(target, AwtComponent::widthID);
duke@0 276 jint height = env->GetIntField(target, AwtComponent::heightID);
duke@0 277
duke@0 278 frame->CreateHWnd(env, L"",
duke@0 279 style,
duke@0 280 exStyle,
duke@0 281 0, 0, 0, 0,
duke@0 282 hwndParent,
duke@0 283 NULL,
duke@0 284 ::GetSysColor(COLOR_WINDOWTEXT),
duke@0 285 ::GetSysColor(COLOR_WINDOWFRAME),
duke@0 286 self);
duke@0 287 /*
duke@0 288 * Reshape here instead of during create, so that a
duke@0 289 * WM_NCCALCSIZE is sent.
duke@0 290 */
duke@0 291 frame->Reshape(x, y, width, height);
duke@0 292 }
duke@0 293 }
duke@0 294 } catch (...) {
duke@0 295 env->DeleteLocalRef(target);
duke@0 296 env->DeleteLocalRef(cls);
duke@0 297 env->DeleteLocalRef(inputMethodWindowCls);
duke@0 298 throw;
duke@0 299 }
duke@0 300
duke@0 301 done:
duke@0 302 env->DeleteLocalRef(target);
duke@0 303 env->DeleteLocalRef(cls);
duke@0 304 env->DeleteLocalRef(inputMethodWindowCls);
duke@0 305
duke@0 306 return frame;
duke@0 307 }
duke@0 308
dcherepanov@3619 309 LRESULT AwtFrame::ProxyWindowProc(UINT message, WPARAM wParam, LPARAM lParam, MsgRouting &mr)
duke@0 310 {
dcherepanov@3619 311 LRESULT retValue = 0L;
duke@0 312
ant@1058 313 AwtComponent *focusOwner = NULL;
dcherepanov@4084 314 AwtComponent *imeTargetComponent = NULL;
dcherepanov@4084 315
duke@0 316 // IME and input language related messages need to be sent to a window
duke@0 317 // which has the Java input focus
duke@0 318 switch (message) {
duke@0 319 case WM_IME_STARTCOMPOSITION:
duke@0 320 case WM_IME_ENDCOMPOSITION:
duke@0 321 case WM_IME_COMPOSITION:
duke@0 322 case WM_IME_SETCONTEXT:
duke@0 323 case WM_IME_NOTIFY:
duke@0 324 case WM_IME_CONTROL:
duke@0 325 case WM_IME_COMPOSITIONFULL:
duke@0 326 case WM_IME_SELECT:
duke@0 327 case WM_IME_CHAR:
dcherepanov@4084 328 case WM_IME_REQUEST:
duke@0 329 case WM_IME_KEYDOWN:
duke@0 330 case WM_IME_KEYUP:
duke@0 331 case WM_INPUTLANGCHANGEREQUEST:
duke@0 332 case WM_INPUTLANGCHANGE:
dcherepanov@4084 333 if (message == WM_IME_STARTCOMPOSITION) {
dcherepanov@4084 334 SetImeTargetComponent(sm_focusOwner);
dcherepanov@4084 335 }
dcherepanov@4084 336 imeTargetComponent = AwtComponent::GetComponent(GetImeTargetComponent());
dcherepanov@4084 337 if (imeTargetComponent != NULL &&
dcherepanov@4084 338 imeTargetComponent != this) // avoid recursive calls
dcherepanov@4084 339 {
dcherepanov@4084 340 retValue = imeTargetComponent->WindowProc(message, wParam, lParam);
dcherepanov@4084 341 mr = mrConsume;
dcherepanov@4084 342 }
dcherepanov@4084 343 if (message == WM_IME_ENDCOMPOSITION) {
dcherepanov@4084 344 SetImeTargetComponent(NULL);
dcherepanov@4084 345 }
dcherepanov@4084 346 break;
ant@1058 347 // TODO: when a Choice's list is dropped down and we're scrolling in
ant@1058 348 // the list WM_MOUSEWHEEL messages come to the poxy, not to the list. Why?
ant@1058 349 case WM_MOUSEWHEEL:
dcherepanov@4084 350 focusOwner = AwtComponent::GetComponent(sm_focusOwner);
dcherepanov@3619 351 if (focusOwner != NULL &&
dcherepanov@3619 352 focusOwner != this) // avoid recursive calls
dcherepanov@3619 353 {
dcherepanov@3619 354 retValue = focusOwner->WindowProc(message, wParam, lParam);
dcherepanov@3619 355 mr = mrConsume;
duke@0 356 }
duke@0 357 break;
ant@1058 358 case WM_SETFOCUS:
dcherepanov@4083 359 if (sm_inSynthesizeFocus) break; // pass it up the WindowProc chain
dcherepanov@4083 360
dcherepanov@3619 361 if (!sm_suppressFocusAndActivation && IsEmbeddedFrame()) {
dcherepanov@3619 362 AwtSetActiveWindow();
ant@1058 363 }
dcherepanov@3619 364 mr = mrConsume;
dcherepanov@3619 365 break;
ant@1058 366 case WM_KILLFOCUS:
dcherepanov@4083 367 if (sm_inSynthesizeFocus) break; // pass it up the WindowProc chain
dcherepanov@4083 368
dcherepanov@3619 369 if (!sm_suppressFocusAndActivation && IsEmbeddedFrame()) {
dcherepanov@3619 370 AwtWindow::SynthesizeWmActivate(FALSE, GetHWnd(), NULL);
ant@1058 371
ant@1058 372 } else if (sm_restoreFocusAndActivation) {
anthony@1066 373 if (AwtComponent::GetFocusedWindow() != NULL) {
anthony@1066 374 AwtWindow *focusedWindow = (AwtWindow*)GetComponent(AwtComponent::GetFocusedWindow());
ant@1058 375 if (focusedWindow != NULL) {
ant@1058 376 // Will just silently restore native focus & activation.
ant@1058 377 focusedWindow->AwtSetActiveWindow();
ant@1058 378 }
ant@1058 379 }
ant@1058 380 }
dcherepanov@3619 381 mr = mrConsume;
dcherepanov@3619 382 break;
duke@0 383 case 0x0127: // WM_CHANGEUISTATE
duke@0 384 case 0x0128: // WM_UPDATEUISTATE
dcherepanov@3619 385 mr = mrConsume;
dcherepanov@3619 386 break;
duke@0 387 }
duke@0 388
dcherepanov@3619 389 return retValue;
duke@0 390 }
duke@0 391
dcherepanov@3619 392 LRESULT AwtFrame::WindowProc(UINT message, WPARAM wParam, LPARAM lParam)
duke@0 393 {
dcherepanov@3619 394 MsgRouting mr = mrDoDefault;
dcherepanov@3619 395 LRESULT retValue = 0L;
dcherepanov@3619 396
dcherepanov@3619 397 retValue = ProxyWindowProc(message, wParam, lParam, mr);
dcherepanov@3619 398
dcherepanov@3619 399 if (mr != mrConsume) {
dcherepanov@3619 400 retValue = AwtWindow::WindowProc(message, wParam, lParam);
ant@1340 401 }
dcherepanov@3619 402 return retValue;
duke@0 403 }
duke@0 404
duke@0 405 MsgRouting AwtFrame::WmShowWindow(BOOL show, UINT status)
duke@0 406 {
duke@0 407 /*
duke@0 408 * Fix for 6492970.
duke@0 409 * When a non-focusable toplevel is shown alone the Java process
duke@0 410 * is not foreground. If one shows another (focusable) toplevel
duke@0 411 * the native platform not always makes it foreground (see the CR).
duke@0 412 * Even worse, sometimes it sends the newly shown toplevel WM_ACTIVATE
duke@0 413 * message. This breaks Java focus. To workaround the problem we
duke@0 414 * set the toplevel being shown foreground programmatically.
duke@0 415 * The fix is localized to non-foreground process case only.
ant@112 416 * (See also: 6599270)
duke@0 417 */
ant@112 418 if (!IsEmbeddedFrame() && show == TRUE && status == 0) {
duke@0 419 HWND fgHWnd = ::GetForegroundWindow();
duke@0 420 if (fgHWnd != NULL) {
duke@0 421 DWORD fgProcessID;
duke@0 422 ::GetWindowThreadProcessId(fgHWnd, &fgProcessID);
duke@0 423
duke@0 424 if (fgProcessID != ::GetCurrentProcessId()) {
duke@0 425 AwtWindow* window = (AwtWindow*)GetComponent(GetHWnd());
duke@0 426
duke@0 427 if (window != NULL && window->IsFocusableWindow() && window->IsAutoRequestFocus() &&
duke@0 428 !::IsWindow(GetModalBlocker(GetHWnd())))
duke@0 429 {
duke@0 430 // When the Java process is not allowed to set the foreground window
duke@0 431 // (see MSDN) the request below will just have no effect.
duke@0 432 ::SetForegroundWindow(GetHWnd());
duke@0 433 }
duke@0 434 }
duke@0 435 }
duke@0 436 }
duke@0 437 return AwtWindow::WmShowWindow(show, status);
duke@0 438 }
duke@0 439
duke@0 440 MsgRouting AwtFrame::WmMouseUp(UINT flags, int x, int y, int button) {
duke@0 441 if (isInManualMoveOrSize) {
duke@0 442 isInManualMoveOrSize = FALSE;
duke@0 443 ::ReleaseCapture();
duke@0 444 return mrConsume;
duke@0 445 }
duke@0 446 return AwtWindow::WmMouseUp(flags, x, y, button);
duke@0 447 }
duke@0 448
duke@0 449 MsgRouting AwtFrame::WmMouseMove(UINT flags, int x, int y) {
duke@0 450 /**
duke@0 451 * If this Frame is non-focusable then we should implement move and size operation for it by
duke@0 452 * ourselfves because we don't dispatch appropriate mouse messages to default window procedure.
duke@0 453 */
duke@0 454 if (!IsFocusableWindow() && isInManualMoveOrSize) {
duke@0 455 DWORD curPos = ::GetMessagePos();
duke@0 456 x = GET_X_LPARAM(curPos);
duke@0 457 y = GET_Y_LPARAM(curPos);
duke@0 458 RECT r;
duke@0 459 ::GetWindowRect(GetHWnd(), &r);
duke@0 460 POINT mouseLoc = {x, y};
duke@0 461 mouseLoc.x -= savedMousePos.x;
duke@0 462 mouseLoc.y -= savedMousePos.y;
duke@0 463 savedMousePos.x = x;
duke@0 464 savedMousePos.y = y;
duke@0 465 if (grabbedHitTest == HTCAPTION) {
duke@0 466 ::SetWindowPos(GetHWnd(), NULL, r.left+mouseLoc.x, r.top+mouseLoc.y,
duke@0 467 r.right-r.left, r.bottom-r.top,
duke@0 468 SWP_NOACTIVATE | SWP_NOSIZE | SWP_NOZORDER);
duke@0 469 } else {
duke@0 470 switch (grabbedHitTest) {
duke@0 471 case HTTOP:
duke@0 472 r.top += mouseLoc.y;
duke@0 473 break;
duke@0 474 case HTBOTTOM:
duke@0 475 r.bottom += mouseLoc.y;
duke@0 476 break;
duke@0 477 case HTRIGHT:
duke@0 478 r.right += mouseLoc.x;
duke@0 479 break;
duke@0 480 case HTLEFT:
duke@0 481 r.left += mouseLoc.x;
duke@0 482 break;
duke@0 483 case HTTOPLEFT:
duke@0 484 r.left += mouseLoc.x;
duke@0 485 r.top += mouseLoc.y;
duke@0 486 break;
duke@0 487 case HTTOPRIGHT:
duke@0 488 r.top += mouseLoc.y;
duke@0 489 r.right += mouseLoc.x;
duke@0 490 break;
duke@0 491 case HTBOTTOMLEFT:
duke@0 492 r.left += mouseLoc.x;
duke@0 493 r.bottom += mouseLoc.y;
duke@0 494 break;
duke@0 495 case HTBOTTOMRIGHT:
duke@0 496 case HTSIZE:
duke@0 497 r.right += mouseLoc.x;
duke@0 498 r.bottom += mouseLoc.y;
duke@0 499 break;
duke@0 500 }
duke@0 501
duke@0 502 ::SetWindowPos(GetHWnd(), NULL, r.left, r.top,
duke@0 503 r.right-r.left, r.bottom-r.top,
anthony@105 504 SWP_NOACTIVATE | SWP_NOZORDER |
duke@0 505 SWP_NOCOPYBITS | SWP_DEFERERASE);
duke@0 506 }
duke@0 507 return mrConsume;
duke@0 508 } else {
duke@0 509 return AwtWindow::WmMouseMove(flags, x, y);
duke@0 510 }
duke@0 511 }
duke@0 512
duke@0 513 MsgRouting AwtFrame::WmNcMouseUp(WPARAM hitTest, int x, int y, int button) {
duke@0 514 if (!IsFocusableWindow() && (button & LEFT_BUTTON)) {
duke@0 515 /*
duke@0 516 * Fix for 6399659.
duke@0 517 * The native system shouldn't activate the next window in z-order
duke@0 518 * when minimizing non-focusable window.
duke@0 519 */
duke@0 520 if (hitTest == HTMINBUTTON) {
duke@0 521 ::ShowWindow(GetHWnd(), SW_SHOWMINNOACTIVE);
duke@0 522 return mrConsume;
duke@0 523 }
duke@0 524 /**
duke@0 525 * If this Frame is non-focusable then we should implement move and size operation for it by
duke@0 526 * ourselfves because we don't dispatch appropriate mouse messages to default window procedure.
duke@0 527 */
duke@0 528 if ((button & DBL_CLICK) && hitTest == HTCAPTION) {
duke@0 529 // Double click on caption - maximize or restore Frame.
duke@0 530 if (IsResizable()) {
duke@0 531 if (::IsZoomed(GetHWnd())) {
duke@0 532 ::ShowWindow(GetHWnd(), SW_SHOWNOACTIVATE);
duke@0 533 } else {
duke@0 534 ::ShowWindow(GetHWnd(), SW_MAXIMIZE);
duke@0 535 }
duke@0 536 }
duke@0 537 return mrConsume;
duke@0 538 }
duke@0 539 switch (hitTest) {
duke@0 540 case HTMAXBUTTON:
duke@0 541 if (IsResizable()) {
duke@0 542 if (::IsZoomed(GetHWnd())) {
duke@0 543 ::ShowWindow(GetHWnd(), SW_SHOWNOACTIVATE);
duke@0 544 } else {
duke@0 545 ::ShowWindow(GetHWnd(), SW_MAXIMIZE);
duke@0 546 }
duke@0 547 }
duke@0 548 return mrConsume;
duke@0 549 default:
duke@0 550 return mrDoDefault;
duke@0 551 }
duke@0 552 }
duke@0 553 return AwtWindow::WmNcMouseUp(hitTest, x, y, button);
duke@0 554 }
duke@0 555
duke@0 556 MsgRouting AwtFrame::WmNcMouseDown(WPARAM hitTest, int x, int y, int button) {
duke@0 557 // By Swing request, click on the Frame's decorations (even on
duke@0 558 // grabbed Frame) should generate UngrabEvent
duke@0 559 if (m_grabbedWindow != NULL/* && !m_grabbedWindow->IsOneOfOwnersOf(this)*/) {
duke@0 560 m_grabbedWindow->Ungrab();
duke@0 561 }
duke@0 562 if (!IsFocusableWindow() && (button & LEFT_BUTTON)) {
duke@0 563 switch (hitTest) {
duke@0 564 case HTTOP:
duke@0 565 case HTBOTTOM:
duke@0 566 case HTLEFT:
duke@0 567 case HTRIGHT:
duke@0 568 case HTTOPLEFT:
duke@0 569 case HTTOPRIGHT:
duke@0 570 case HTBOTTOMLEFT:
duke@0 571 case HTBOTTOMRIGHT:
duke@0 572 case HTSIZE:
duke@0 573 // Zoomed or non-resizable unfocusable frames should not be resizable.
duke@0 574 if (isZoomed() || !IsResizable()) {
duke@0 575 return mrConsume;
duke@0 576 }
duke@0 577 case HTCAPTION:
duke@0 578 // We are going to perform default mouse action on non-client area of this window
duke@0 579 // Grab mouse for this purpose and store coordinates for motion vector calculation
duke@0 580 savedMousePos.x = x;
duke@0 581 savedMousePos.y = y;
duke@0 582 ::SetCapture(GetHWnd());
duke@0 583 isInManualMoveOrSize = TRUE;
duke@0 584 grabbedHitTest = hitTest;
duke@0 585 return mrConsume;
duke@0 586 default:
duke@0 587 return mrDoDefault;
duke@0 588 }
duke@0 589 }
duke@0 590 return AwtWindow::WmNcMouseDown(hitTest, x, y, button);
duke@0 591 }
duke@0 592
duke@0 593 // Override AwtWindow::Reshape() to handle minimized/maximized
duke@0 594 // frames (see 6525850, 4065534)
duke@0 595 void AwtFrame::Reshape(int x, int y, int width, int height)
duke@0 596 {
duke@0 597 if (isIconic()) {
duke@0 598 // normal AwtComponent::Reshape will not work for iconified windows so...
duke@0 599 WINDOWPLACEMENT wp;
duke@0 600 POINT ptMinPosition = {x,y};
duke@0 601 POINT ptMaxPosition = {0,0};
duke@0 602 RECT rcNormalPosition = {x,y,x+width,y+height};
duke@0 603 RECT rcWorkspace;
duke@0 604 HWND hWndDesktop = GetDesktopWindow();
duke@0 605 HWND hWndSelf = GetHWnd();
duke@0 606
duke@0 607 // SetWindowPlacement takes workspace coordinates, but
duke@0 608 // if taskbar is at top of screen, workspace coords !=
duke@0 609 // screen coords, so offset by workspace origin
duke@0 610 VERIFY(::SystemParametersInfo(SPI_GETWORKAREA, 0, (PVOID)&rcWorkspace, 0));
duke@0 611 ::OffsetRect(&rcNormalPosition, -rcWorkspace.left, -rcWorkspace.top);
duke@0 612
duke@0 613 // set the window size for when it is not-iconified
duke@0 614 wp.length = sizeof(wp);
duke@0 615 wp.flags = WPF_SETMINPOSITION;
duke@0 616 wp.showCmd = IsVisible() ? SW_SHOWMINIMIZED : SW_HIDE;
duke@0 617 wp.ptMinPosition = ptMinPosition;
duke@0 618 wp.ptMaxPosition = ptMaxPosition;
duke@0 619 wp.rcNormalPosition = rcNormalPosition;
duke@0 620
duke@0 621 // If the call is not guarded with ignoreWmSize,
duke@0 622 // a regression for bug 4851435 appears.
duke@0 623 // Having this call guarded also prevents
duke@0 624 // changing the iconified state of the frame
duke@0 625 // while calling the Frame.setBounds() method.
duke@0 626 m_ignoreWmSize = TRUE;
duke@0 627 ::SetWindowPlacement(hWndSelf, &wp);
duke@0 628 m_ignoreWmSize = FALSE;
duke@0 629
duke@0 630 return;
duke@0 631 }
duke@0 632
duke@0 633 if (isZoomed()) {
duke@0 634 // setting size of maximized window, we remove the
duke@0 635 // maximized state bit (matches Motif behaviour)
duke@0 636 // (calling ShowWindow(SW_RESTORE) would fire an
duke@0 637 // activation event which we don't want)
duke@0 638 LONG style = GetStyle();
duke@0 639 DASSERT(style & WS_MAXIMIZE);
duke@0 640 style ^= WS_MAXIMIZE;
duke@0 641 SetStyle(style);
duke@0 642 }
duke@0 643
duke@0 644 AwtWindow::Reshape(x, y, width, height);
duke@0 645 }
duke@0 646
duke@0 647
duke@0 648 /* Show the frame in it's current state */
duke@0 649 void
duke@0 650 AwtFrame::Show()
duke@0 651 {
duke@0 652 m_visible = true;
duke@0 653 HWND hwnd = GetHWnd();
duke@0 654 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
duke@0 655
duke@0 656 DTRACE_PRINTLN3("AwtFrame::Show:%s%s%s",
duke@0 657 m_iconic ? " iconic" : "",
duke@0 658 m_zoomed ? " zoomed" : "",
duke@0 659 m_iconic || m_zoomed ? "" : " normal");
duke@0 660
duke@0 661 BOOL locationByPlatform = env->GetBooleanField(GetTarget(env), AwtWindow::locationByPlatformID);
duke@0 662
duke@0 663 if (locationByPlatform) {
duke@0 664 moveToDefaultLocation();
duke@0 665 }
anthony@1614 666 EnableTranslucency(TRUE);
anthony@1614 667
duke@0 668 BOOL autoRequestFocus = IsAutoRequestFocus();
duke@0 669
duke@0 670 if (m_iconic) {
duke@0 671 if (m_zoomed) {
duke@0 672 // This whole function could probably be rewritten to use
duke@0 673 // ::SetWindowPlacement but MS docs doesn't tell if
duke@0 674 // ::SetWindowPlacement is a proper superset of
duke@0 675 // ::ShowWindow. So let's be conservative and only use it
duke@0 676 // here, where we really do need it.
duke@0 677 DTRACE_PRINTLN("AwtFrame::Show(SW_SHOWMINIMIZED, WPF_RESTORETOMAXIMIZED");
duke@0 678 WINDOWPLACEMENT wp;
duke@0 679 ::ZeroMemory(&wp, sizeof(WINDOWPLACEMENT));
duke@0 680 wp.length = sizeof(WINDOWPLACEMENT);
duke@0 681 ::GetWindowPlacement(hwnd, &wp);
duke@0 682 if (!IsFocusableWindow() || !autoRequestFocus) {
duke@0 683 wp.showCmd = SW_SHOWMINNOACTIVE;
duke@0 684 } else {
duke@0 685 wp.showCmd = SW_SHOWMINIMIZED;
duke@0 686 }
duke@0 687 wp.flags |= WPF_RESTORETOMAXIMIZED;
duke@0 688 ::SetWindowPlacement(hwnd, &wp);
duke@0 689 }
duke@0 690 else {
duke@0 691 DTRACE_PRINTLN("AwtFrame::Show(SW_SHOWMINIMIZED)");
duke@0 692 if (!IsFocusableWindow() || !autoRequestFocus) {
duke@0 693 ::ShowWindow(hwnd, SW_SHOWMINNOACTIVE);
duke@0 694 } else {
duke@0 695 ::ShowWindow(hwnd, SW_SHOWMINIMIZED);
duke@0 696 }
duke@0 697 }
duke@0 698 }
duke@0 699 else if (m_zoomed) {
duke@0 700 DTRACE_PRINTLN("AwtFrame::Show(SW_SHOWMAXIMIZED)");
duke@0 701 if (!autoRequestFocus) {
duke@0 702
duke@0 703 m_filterFocusAndActivation = TRUE;
duke@0 704 ::ShowWindow(hwnd, SW_MAXIMIZE);
duke@0 705 m_filterFocusAndActivation = FALSE;
duke@0 706
duke@0 707 } else if (!IsFocusableWindow()) {
duke@0 708 ::ShowWindow(hwnd, SW_MAXIMIZE);
duke@0 709 } else {
duke@0 710 ::ShowWindow(hwnd, SW_SHOWMAXIMIZED);
duke@0 711 }
duke@0 712 }
duke@0 713 else if (m_isInputMethodWindow) {
duke@0 714 // Don't activate input methow window
duke@0 715 DTRACE_PRINTLN("AwtFrame::Show(SW_SHOWNA)");
duke@0 716 ::ShowWindow(hwnd, SW_SHOWNA);
duke@0 717
duke@0 718 // After the input method window shown, we have to adjust the
duke@0 719 // IME candidate window position. Here is why.
duke@0 720 // Usually, when IMM opens the candidate window, it sends WM_IME_NOTIFY w/
duke@0 721 // IMN_OPENCANDIDATE message to the awt component window. The
duke@0 722 // awt component makes a Java call to acquire the text position
duke@0 723 // in order to show the candidate window just below the input method window.
duke@0 724 // However, by the time it acquires the position, the input method window
duke@0 725 // hasn't been displayed yet, the position returned is just below
duke@0 726 // the composed text and when the input method window is shown, it
duke@0 727 // will hide part of the candidate list. To fix this, we have to
duke@0 728 // adjust the candidate window position after the input method window
duke@0 729 // is shown. See bug 5012944.
duke@0 730 AdjustCandidateWindowPos();
duke@0 731 }
duke@0 732 else {
duke@0 733 // Nor iconic, nor zoomed (handled above) - so use SW_RESTORE
duke@0 734 // to show in "normal" state regardless of whatever stale
duke@0 735 // state might the invisible window still has.
duke@0 736 DTRACE_PRINTLN("AwtFrame::Show(SW_RESTORE)");
duke@0 737 if (!IsFocusableWindow() || !autoRequestFocus) {
duke@0 738 ::ShowWindow(hwnd, SW_SHOWNOACTIVATE);
duke@0 739 } else {
duke@0 740 ::ShowWindow(hwnd, SW_RESTORE);
duke@0 741 }
duke@0 742 }
duke@0 743 }
duke@0 744
duke@0 745 void
duke@0 746 AwtFrame::SendWindowStateEvent(int oldState, int newState)
duke@0 747 {
duke@0 748 SendWindowEvent(java_awt_event_WindowEvent_WINDOW_STATE_CHANGED,
duke@0 749 NULL, oldState, newState);
duke@0 750 }
duke@0 751
duke@0 752 void
duke@0 753 AwtFrame::ClearMaximizedBounds()
duke@0 754 {
duke@0 755 m_maxBoundsSet = FALSE;
duke@0 756 }
duke@0 757
duke@0 758 void AwtFrame::AdjustCandidateWindowPos()
duke@0 759 {
duke@0 760 // This method should only be called if the current frame
duke@0 761 // is the input method window frame.
duke@0 762 if (!m_isInputMethodWindow) {
duke@0 763 return;
duke@0 764 }
duke@0 765
duke@0 766 RECT inputWinRec, focusWinRec;
duke@0 767 AwtComponent *comp = AwtComponent::GetComponent(AwtComponent::sm_focusOwner);
duke@0 768 if (comp == NULL) {
duke@0 769 return;
duke@0 770 }
duke@0 771
duke@0 772 ::GetWindowRect(GetHWnd(), &inputWinRec);
duke@0 773 ::GetWindowRect(sm_focusOwner, &focusWinRec);
duke@0 774
duke@0 775 LPARAM candType = comp->GetCandidateType();
duke@0 776 HWND defaultIMEWnd = ::ImmGetDefaultIMEWnd(GetHWnd());
duke@0 777 if (defaultIMEWnd == NULL) {
duke@0 778 return;
duke@0 779 }
duke@0 780 UINT bits = 1;
duke@0 781 // adjusts the candidate window position
duke@0 782 for (int iCandType = 0; iCandType < 32; iCandType++, bits<<=1) {
duke@0 783 if (candType & bits) {
duke@0 784 CANDIDATEFORM cf;
duke@0 785 cf.dwIndex = iCandType;
duke@0 786 cf.dwStyle = CFS_CANDIDATEPOS;
duke@0 787 // Since the coordinates are relative to the containing window,
duke@0 788 // we have to calculate the coordinates as below.
duke@0 789 cf.ptCurrentPos.x = inputWinRec.left - focusWinRec.left;
duke@0 790 cf.ptCurrentPos.y = inputWinRec.bottom - focusWinRec.top;
duke@0 791
duke@0 792 // sends IMC_SETCANDIDATEPOS to IMM to move the candidate window.
duke@0 793 ::SendMessage(defaultIMEWnd, WM_IME_CONTROL, IMC_SETCANDIDATEPOS, (LPARAM)&cf);
duke@0 794 }
duke@0 795 }
duke@0 796 }
duke@0 797
duke@0 798 void
duke@0 799 AwtFrame::SetMaximizedBounds(int x, int y, int w, int h)
duke@0 800 {
duke@0 801 m_maxPos.x = x;
duke@0 802 m_maxPos.y = y;
duke@0 803 m_maxSize.x = w;
duke@0 804 m_maxSize.y = h;
duke@0 805 m_maxBoundsSet = TRUE;
duke@0 806 }
duke@0 807
duke@0 808 MsgRouting AwtFrame::WmGetMinMaxInfo(LPMINMAXINFO lpmmi)
duke@0 809 {
duke@0 810 //Firstly call AwtWindow's function
duke@0 811 MsgRouting r = AwtWindow::WmGetMinMaxInfo(lpmmi);
duke@0 812
duke@0 813 //Then replace maxPos & maxSize if necessary
duke@0 814 if (!m_maxBoundsSet) {
duke@0 815 return r;
duke@0 816 }
duke@0 817
duke@0 818 if (m_maxPos.x != java_lang_Integer_MAX_VALUE)
duke@0 819 lpmmi->ptMaxPosition.x = m_maxPos.x;
duke@0 820 if (m_maxPos.y != java_lang_Integer_MAX_VALUE)
duke@0 821 lpmmi->ptMaxPosition.y = m_maxPos.y;
duke@0 822 if (m_maxSize.x != java_lang_Integer_MAX_VALUE)
duke@0 823 lpmmi->ptMaxSize.x = m_maxSize.x;
duke@0 824 if (m_maxSize.y != java_lang_Integer_MAX_VALUE)
duke@0 825 lpmmi->ptMaxSize.y = m_maxSize.y;
duke@0 826 return mrConsume;
duke@0 827 }
duke@0 828
duke@0 829 MsgRouting AwtFrame::WmSize(UINT type, int w, int h)
duke@0 830 {
anthony@1066 831 currentWmSizeState = type;
anthony@1066 832 if (currentWmSizeState == SIZE_MINIMIZED) {
anthony@1066 833 UpdateSecurityWarningVisibility();
anthony@1066 834 }
anthony@1066 835
duke@0 836 if (m_ignoreWmSize) {
duke@0 837 return mrDoDefault;
duke@0 838 }
duke@0 839
duke@0 840 DTRACE_PRINTLN6("AwtFrame::WmSize: %dx%d,%s visible, state%s%s%s",
duke@0 841 w, h,
duke@0 842 ::IsWindowVisible(GetHWnd()) ? "" : " not",
duke@0 843 m_iconic ? " iconic" : "",
duke@0 844 m_zoomed ? " zoomed" : "",
duke@0 845 m_iconic || m_zoomed ? "" : " normal");
duke@0 846
duke@0 847 BOOL iconify = type == SIZE_MINIMIZED;
duke@0 848
duke@0 849 // Note that zoom may be set to TRUE in several cases:
duke@0 850 // 1. type == SIZE_MAXIMIZED means that either the user or
duke@0 851 // the developer (via setExtendedState(MAXIMIZED_BOTH)
duke@0 852 // maximizes the frame.
duke@0 853 // 2. type == SIZE_MINIMIZED && isZoomed() means that a maximized
duke@0 854 // frame is to be minimized. If the user minimizes a maximized
duke@0 855 // frame, we need to keep the zoomed property TRUE. However,
duke@0 856 // if the developer calls setExtendedState(ICONIFIED), i.e.
duke@0 857 // w/o combining the ICONIFIED state with the MAXIMIZED state,
duke@0 858 // we MUST RESET the zoomed property.
duke@0 859 // The flag m_forceResetZoomed identifies the latter case.
duke@0 860 BOOL zoom =
duke@0 861 (
duke@0 862 type == SIZE_MAXIMIZED
duke@0 863 ||
duke@0 864 (type == SIZE_MINIMIZED && isZoomed())
duke@0 865 )
duke@0 866 && !m_forceResetZoomed;
duke@0 867
duke@0 868 // Set the new state and send appropriate Java event
duke@0 869 jint oldState = java_awt_Frame_NORMAL;
duke@0 870 if (isIconic()) {
duke@0 871 oldState |= java_awt_Frame_ICONIFIED;
duke@0 872 }
duke@0 873 if (isZoomed()) {
duke@0 874 oldState |= java_awt_Frame_MAXIMIZED_BOTH;
duke@0 875 }
duke@0 876
duke@0 877 jint newState = java_awt_Frame_NORMAL;
duke@0 878 if (iconify) {
duke@0 879 newState |= java_awt_Frame_ICONIFIED;
duke@0 880 }
duke@0 881 if (zoom) {
duke@0 882 newState |= java_awt_Frame_MAXIMIZED_BOTH;
duke@0 883 }
duke@0 884
duke@0 885 setIconic(iconify);
duke@0 886 setZoomed(zoom);
duke@0 887
duke@0 888 jint changed = oldState ^ newState;
duke@0 889 if (changed != 0) {
duke@0 890 DTRACE_PRINTLN2("AwtFrame::WmSize: reporting state change %x -> %x",
duke@0 891 oldState, newState);
dcherepanov@1047 892
dcherepanov@1047 893 // sync target with peer
dcherepanov@1047 894 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
dcherepanov@1047 895 env->CallVoidMethod(GetPeer(env), AwtFrame::setExtendedStateMID, newState);
dcherepanov@1047 896
duke@0 897 // report (de)iconification to old clients
duke@0 898 if (changed & java_awt_Frame_ICONIFIED) {
duke@0 899 if (newState & java_awt_Frame_ICONIFIED) {
duke@0 900 SendWindowEvent(java_awt_event_WindowEvent_WINDOW_ICONIFIED);
duke@0 901 } else {
duke@0 902 SendWindowEvent(java_awt_event_WindowEvent_WINDOW_DEICONIFIED);
duke@0 903 }
duke@0 904 }
duke@0 905
duke@0 906 // New (since 1.4) state change event
duke@0 907 SendWindowStateEvent(oldState, newState);
duke@0 908 }
duke@0 909
duke@0 910 // If window is in iconic state, do not send COMPONENT_RESIZED event
duke@0 911 if (isIconic()) {
duke@0 912 return mrDoDefault;
duke@0 913 }
duke@0 914
duke@0 915 return AwtWindow::WmSize(type, w, h);
duke@0 916 }
duke@0 917
duke@0 918 MsgRouting AwtFrame::WmActivate(UINT nState, BOOL fMinimized, HWND opposite)
duke@0 919 {
duke@0 920 jint type;
duke@0 921
duke@0 922 if (nState != WA_INACTIVE) {
ant@1058 923 if (::IsWindow(AwtWindow::GetModalBlocker(GetHWnd())) ||
ant@1058 924 CheckActivateActualFocusedWindow(opposite))
ant@1058 925 {
ant@1058 926 return mrConsume;
ant@1058 927 }
ant@1058 928 type = java_awt_event_WindowEvent_WINDOW_GAINED_FOCUS;
anthony@1066 929 AwtComponent::SetFocusedWindow(GetHWnd());
duke@0 930
duke@0 931 } else {
duke@0 932 if (!::IsWindow(AwtWindow::GetModalBlocker(opposite))) {
duke@0 933 // If deactivation happens because of press on grabbing
duke@0 934 // window - this is nonsense, since grabbing window is
duke@0 935 // assumed to have focus and watch for deactivation. But
duke@0 936 // this can happen - if grabbing window is proxied Window,
duke@0 937 // with Frame keeping real focus for it.
duke@0 938 if (m_grabbedWindow != NULL) {
duke@0 939 if (m_grabbedWindow->GetHWnd() == opposite) {
duke@0 940 // Do nothing
duke@0 941 } else {
duke@0 942 // Normally, we would rather check that this ==
duke@0 943 // grabbed window, and focus is leaving it -
duke@0 944 // ungrab. But since we know about proxied
duke@0 945 // windows, we simply assume this is one of the
duke@0 946 // known cases.
duke@0 947 if (!m_grabbedWindow->IsOneOfOwnersOf((AwtWindow*)AwtComponent::GetComponent(opposite))) {
duke@0 948 m_grabbedWindow->Ungrab();
duke@0 949 }
duke@0 950 }
duke@0 951 }
ant@1058 952 CheckRetainActualFocusedWindow(opposite);
duke@0 953
duke@0 954 type = java_awt_event_WindowEvent_WINDOW_LOST_FOCUS;
anthony@1066 955 AwtComponent::SetFocusedWindow(NULL);
ant@1058 956 sm_focusOwner = NULL;
duke@0 957 }
duke@0 958 }
duke@0 959
ant@1058 960 SendWindowEvent(type, opposite);
ant@1058 961 return mrConsume;
ant@1058 962 }
ant@1058 963
ant@1058 964 BOOL AwtFrame::CheckActivateActualFocusedWindow(HWND deactivatedOpositeHWnd)
ant@1058 965 {
ant@1058 966 if (m_actualFocusedWindow != NULL) {
ant@1058 967 HWND hwnd = m_actualFocusedWindow->GetHWnd();
ant@1058 968 if (hwnd != NULL && ::IsWindowVisible(hwnd)) {
ant@1058 969 SynthesizeWmActivate(TRUE, hwnd, deactivatedOpositeHWnd);
ant@1058 970 return TRUE;
ant@1058 971 }
ant@1058 972 m_actualFocusedWindow = NULL;
duke@0 973 }
ant@1058 974 return FALSE;
ant@1058 975 }
ant@1058 976
ant@1058 977 void AwtFrame::CheckRetainActualFocusedWindow(HWND activatedOpositeHWnd)
ant@1058 978 {
ant@1058 979 // If actual focused window is not this Frame
anthony@1066 980 if (AwtComponent::GetFocusedWindow() != GetHWnd()) {
ant@1058 981 // Make sure the actual focused window is an owned window of this frame
anthony@1066 982 AwtWindow *focusedWindow = (AwtWindow *)AwtComponent::GetComponent(AwtComponent::GetFocusedWindow());
ant@1058 983 if (focusedWindow != NULL && focusedWindow->GetOwningFrameOrDialog() == this) {
ant@1058 984
ant@1058 985 // Check that the opposite window is not this frame, nor an owned window of this frame
ant@1058 986 if (activatedOpositeHWnd != NULL) {
ant@1058 987 AwtWindow *oppositeWindow = (AwtWindow *)AwtComponent::GetComponent(activatedOpositeHWnd);
ant@1058 988 if (oppositeWindow && oppositeWindow != this &&
ant@1058 989 oppositeWindow->GetOwningFrameOrDialog() != this)
ant@1058 990 {
ant@1058 991 m_actualFocusedWindow = focusedWindow;
ant@1058 992 }
ant@1058 993 } else {
ant@1058 994 m_actualFocusedWindow = focusedWindow;
ant@1058 995 }
ant@1058 996 }
ant@1058 997 }
ant@1058 998 }
ant@1058 999
ant@1058 1000 BOOL AwtFrame::AwtSetActiveWindow(BOOL isMouseEventCause, UINT hittest)
ant@1058 1001 {
ant@1058 1002 if (hittest == HTCLIENT) {
ant@1058 1003 // Don't let the actualFocusedWindow to steal focus if:
ant@1058 1004 // a) the frame is clicked in its client area;
ant@1058 1005 // b) focus is requested to some of the frame's child.
ant@1058 1006 m_actualFocusedWindow = NULL;
ant@1058 1007 }
ant@1058 1008 return AwtWindow::AwtSetActiveWindow(isMouseEventCause);
duke@0 1009 }
duke@0 1010
duke@0 1011 MsgRouting AwtFrame::WmEnterMenuLoop(BOOL isTrackPopupMenu)
duke@0 1012 {
duke@0 1013 if ( !isTrackPopupMenu ) {
duke@0 1014 m_isMenuDropped = TRUE;
duke@0 1015 }
duke@0 1016 return mrDoDefault;
duke@0 1017 }
duke@0 1018
duke@0 1019 MsgRouting AwtFrame::WmExitMenuLoop(BOOL isTrackPopupMenu)
duke@0 1020 {
duke@0 1021 if ( !isTrackPopupMenu ) {
duke@0 1022 m_isMenuDropped = FALSE;
duke@0 1023 }
duke@0 1024 return mrDoDefault;
duke@0 1025 }
duke@0 1026
duke@0 1027 AwtMenuBar* AwtFrame::GetMenuBar()
duke@0 1028 {
duke@0 1029 return menuBar;
duke@0 1030 }
duke@0 1031
duke@0 1032 void AwtFrame::SetMenuBar(AwtMenuBar* mb)
duke@0 1033 {
duke@0 1034 menuBar = mb;
duke@0 1035 if (mb == NULL) {
duke@0 1036 // Remove existing menu bar, if any.
duke@0 1037 ::SetMenu(GetHWnd(), NULL);
duke@0 1038 } else {
duke@0 1039 if (menuBar->GetHMenu() != NULL) {
duke@0 1040 ::SetMenu(GetHWnd(), menuBar->GetHMenu());
duke@0 1041 }
duke@0 1042 }
duke@0 1043 }
duke@0 1044
duke@0 1045 MsgRouting AwtFrame::WmDrawItem(UINT ctrlId, DRAWITEMSTRUCT& drawInfo)
duke@0 1046 {
duke@0 1047 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
duke@0 1048
duke@0 1049 // if the item to be redrawn is the menu bar, then do it
duke@0 1050 AwtMenuBar* awtMenubar = GetMenuBar();
duke@0 1051 if (drawInfo.CtlType == ODT_MENU && (awtMenubar != NULL) &&
duke@0 1052 (::GetMenu( GetHWnd() ) == (HMENU)drawInfo.hwndItem) )
duke@0 1053 {
duke@0 1054 awtMenubar->DrawItem(drawInfo);
duke@0 1055 return mrConsume;
duke@0 1056 }
duke@0 1057
duke@0 1058 return AwtComponent::WmDrawItem(ctrlId, drawInfo);
duke@0 1059 }
duke@0 1060
duke@0 1061 MsgRouting AwtFrame::WmMeasureItem(UINT ctrlId, MEASUREITEMSTRUCT& measureInfo)
duke@0 1062 {
duke@0 1063 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
duke@0 1064 AwtMenuBar* awtMenubar = GetMenuBar();
duke@0 1065 if ((measureInfo.CtlType == ODT_MENU) && (awtMenubar != NULL))
duke@0 1066 {
duke@0 1067 // AwtMenu instance is stored in itemData. Use it to check if this
duke@0 1068 // menu is the menu bar.
duke@0 1069 AwtMenu * pMenu = (AwtMenu *) measureInfo.itemData;
duke@0 1070 DASSERT(pMenu != NULL);
duke@0 1071 if ( pMenu == awtMenubar )
duke@0 1072 {
duke@0 1073 HWND hWnd = GetHWnd();
duke@0 1074 HDC hDC = ::GetDC(hWnd);
duke@0 1075 DASSERT(hDC != NULL);
duke@0 1076 awtMenubar->MeasureItem(hDC, measureInfo);
duke@0 1077 VERIFY(::ReleaseDC(hWnd, hDC));
duke@0 1078 return mrConsume;
duke@0 1079 }
duke@0 1080 }
duke@0 1081
duke@0 1082 return AwtComponent::WmMeasureItem(ctrlId, measureInfo);
duke@0 1083 }
duke@0 1084
duke@0 1085 MsgRouting AwtFrame::WmGetIcon(WPARAM iconType, LRESULT& retVal)
duke@0 1086 {
duke@0 1087 //Workaround windows bug:
duke@0 1088 //when reseting from specific icon to class icon
duke@0 1089 //taskbar is not updated
duke@0 1090 if (iconType <= 2 /*ICON_SMALL2*/) {
duke@0 1091 retVal = (LRESULT)GetEffectiveIcon(iconType);
duke@0 1092 return mrConsume;
duke@0 1093 } else {
duke@0 1094 return mrDoDefault;
duke@0 1095 }
duke@0 1096 }
duke@0 1097
duke@0 1098 void AwtFrame::DoUpdateIcon()
duke@0 1099 {
duke@0 1100 //Workaround windows bug:
duke@0 1101 //when reseting from specific icon to class icon
duke@0 1102 //taskbar is not updated
duke@0 1103 HICON hIcon = GetEffectiveIcon(ICON_BIG);
duke@0 1104 HICON hIconSm = GetEffectiveIcon(ICON_SMALL);
duke@0 1105 SendMessage(WM_SETICON, ICON_BIG, (LPARAM)hIcon);
duke@0 1106 SendMessage(WM_SETICON, ICON_SMALL, (LPARAM)hIconSm);
duke@0 1107 }
duke@0 1108
duke@0 1109 HICON AwtFrame::GetEffectiveIcon(int iconType)
duke@0 1110 {
duke@0 1111 BOOL smallIcon = ((iconType == ICON_SMALL) || (iconType == 2/*ICON_SMALL2*/));
duke@0 1112 HICON hIcon = (smallIcon) ? GetHIconSm() : GetHIcon();
duke@0 1113 if (hIcon == NULL) {
duke@0 1114 hIcon = (smallIcon) ? AwtToolkit::GetInstance().GetAwtIconSm() :
duke@0 1115 AwtToolkit::GetInstance().GetAwtIcon();
duke@0 1116 }
duke@0 1117 return hIcon;
duke@0 1118 }
duke@0 1119
duke@0 1120 static BOOL keepOnMinimize(jobject peer) {
duke@0 1121 static BOOL checked = FALSE;
duke@0 1122 static BOOL keep = FALSE;
duke@0 1123 if (!checked) {
duke@0 1124 keep = (JNU_GetStaticFieldByName(AwtToolkit::GetEnv(), NULL,
duke@0 1125 "sun/awt/windows/WFramePeer", "keepOnMinimize", "Z").z) == JNI_TRUE;
duke@0 1126 checked = TRUE;
duke@0 1127 }
duke@0 1128 return keep;
duke@0 1129 }
duke@0 1130
duke@0 1131 MsgRouting AwtFrame::WmSysCommand(UINT uCmdType, int xPos, int yPos)
duke@0 1132 {
duke@0 1133 // ignore any WM_SYSCOMMAND if this window is blocked by modal dialog
duke@0 1134 if (::IsWindow(AwtWindow::GetModalBlocker(GetHWnd()))) {
duke@0 1135 return mrConsume;
duke@0 1136 }
duke@0 1137
duke@0 1138 if (uCmdType == (SYSCOMMAND_IMM & 0xFFF0)){
duke@0 1139 JNIEnv* env = AwtToolkit::GetEnv();
duke@0 1140 JNU_CallMethodByName(env, NULL, m_peerObject,
duke@0 1141 "notifyIMMOptionChange", "()V");
duke@0 1142 DASSERT(!safe_ExceptionOccurred(env));
duke@0 1143 return mrConsume;
duke@0 1144 }
duke@0 1145 if ((uCmdType == SC_MINIMIZE) && keepOnMinimize(m_peerObject)) {
duke@0 1146 ::ShowWindow(GetHWnd(),SW_SHOWMINIMIZED);
duke@0 1147 return mrConsume;
duke@0 1148 }
duke@0 1149 return AwtWindow::WmSysCommand(uCmdType, xPos, yPos);
duke@0 1150 }
duke@0 1151
duke@0 1152 LRESULT AwtFrame::WinThreadExecProc(ExecuteArgs * args)
duke@0 1153 {
duke@0 1154 switch( args->cmdId ) {
duke@0 1155 case FRAME_SETMENUBAR:
duke@0 1156 {
duke@0 1157 jobject mbPeer = (jobject)args->param1;
duke@0 1158
duke@0 1159 // cancel any currently dropped down menus
duke@0 1160 if (m_isMenuDropped) {
duke@0 1161 SendMessage(WM_CANCELMODE);
duke@0 1162 }
duke@0 1163
duke@0 1164 if (mbPeer == NULL) {
duke@0 1165 // Remove existing menu bar, if any
duke@0 1166 SetMenuBar(NULL);
duke@0 1167 } else {
duke@0 1168 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
duke@0 1169 AwtMenuBar* menuBar = (AwtMenuBar *)JNI_GET_PDATA(mbPeer);
duke@0 1170 SetMenuBar(menuBar);
duke@0 1171 }
duke@0 1172 DrawMenuBar();
duke@0 1173 break;
duke@0 1174 }
duke@0 1175
duke@0 1176 default:
duke@0 1177 AwtWindow::WinThreadExecProc(args);
duke@0 1178 break;
duke@0 1179 }
duke@0 1180
duke@0 1181 return 0L;
duke@0 1182 }
duke@0 1183
duke@0 1184 void AwtFrame::_SynthesizeWmActivate(void *param)
duke@0 1185 {
duke@0 1186 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
duke@0 1187
duke@0 1188 SynthesizeWmActivateStruct *sas = (SynthesizeWmActivateStruct *)param;
duke@0 1189 jobject self = sas->frame;
duke@0 1190 jboolean doActivate = sas->doActivate;
duke@0 1191
duke@0 1192 AwtFrame *frame = NULL;
duke@0 1193
duke@0 1194 PDATA pData;
duke@0 1195 JNI_CHECK_PEER_GOTO(self, ret);
duke@0 1196 frame = (AwtFrame *)pData;
duke@0 1197
ant@1058 1198 SynthesizeWmActivate(doActivate, frame->GetHWnd(), NULL);
duke@0 1199 ret:
duke@0 1200 env->DeleteGlobalRef(self);
duke@0 1201
duke@0 1202 delete sas;
duke@0 1203 }
duke@0 1204
duke@0 1205 jobject AwtFrame::_GetBoundsPrivate(void *param)
duke@0 1206 {
duke@0 1207 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
duke@0 1208
duke@0 1209 jobject self = (jobject)param;
duke@0 1210
duke@0 1211 jobject result = NULL;
duke@0 1212 AwtFrame *f = NULL;
duke@0 1213
duke@0 1214 PDATA pData;
duke@0 1215 JNI_CHECK_PEER_GOTO(self, ret);
duke@0 1216 f = (AwtFrame *)pData;
duke@0 1217 if (::IsWindow(f->GetHWnd()))
duke@0 1218 {
duke@0 1219 RECT rect;
duke@0 1220 ::GetWindowRect(f->GetHWnd(), &rect);
duke@0 1221 HWND parent = ::GetParent(f->GetHWnd());
duke@0 1222 if (::IsWindow(parent))
duke@0 1223 {
duke@0 1224 POINT zero;
duke@0 1225 zero.x = 0;
duke@0 1226 zero.y = 0;
duke@0 1227 ::ClientToScreen(parent, &zero);
duke@0 1228 ::OffsetRect(&rect, -zero.x, -zero.y);
duke@0 1229 }
duke@0 1230
duke@0 1231 result = JNU_NewObjectByName(env, "java/awt/Rectangle", "(IIII)V",
duke@0 1232 rect.left, rect.top, rect.bottom-rect.top, rect.right-rect.left);
duke@0 1233 }
duke@0 1234 ret:
duke@0 1235 env->DeleteGlobalRef(self);
duke@0 1236
duke@0 1237 if (result != NULL)
duke@0 1238 {
duke@0 1239 jobject resultGlobalRef = env->NewGlobalRef(result);
duke@0 1240 env->DeleteLocalRef(result);
duke@0 1241 return resultGlobalRef;
duke@0 1242 }
duke@0 1243 else
duke@0 1244 {
duke@0 1245 return NULL;
duke@0 1246 }
duke@0 1247 }
duke@0 1248
duke@0 1249 void AwtFrame::_SetState(void *param)
duke@0 1250 {
duke@0 1251 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
duke@0 1252
duke@0 1253 SetStateStruct *sss = (SetStateStruct *)param;
duke@0 1254 jobject self = sss->frame;
duke@0 1255 jint state = sss->state;
duke@0 1256
duke@0 1257 AwtFrame *f = NULL;
duke@0 1258
duke@0 1259 PDATA pData;
duke@0 1260 JNI_CHECK_PEER_GOTO(self, ret);
duke@0 1261 f = (AwtFrame *)pData;
duke@0 1262 HWND hwnd = f->GetHWnd();
duke@0 1263 if (::IsWindow(hwnd))
duke@0 1264 {
duke@0 1265 DASSERT(!IsBadReadPtr(f, sizeof(AwtFrame)));
duke@0 1266
duke@0 1267 BOOL iconify = (state & java_awt_Frame_ICONIFIED) != 0;
duke@0 1268 BOOL zoom = (state & java_awt_Frame_MAXIMIZED_BOTH)
duke@0 1269 == java_awt_Frame_MAXIMIZED_BOTH;
duke@0 1270
duke@0 1271 DTRACE_PRINTLN4("WFramePeer.setState:%s%s ->%s%s",
duke@0 1272 f->isIconic() ? " iconic" : "",
duke@0 1273 f->isZoomed() ? " zoomed" : "",
duke@0 1274 iconify ? " iconic" : "",
duke@0 1275 zoom ? " zoomed" : "");
duke@0 1276
duke@0 1277 if (::IsWindowVisible(hwnd)) {
duke@0 1278 BOOL focusable = f->IsFocusableWindow();
duke@0 1279
duke@0 1280 WINDOWPLACEMENT wp;
duke@0 1281 ::ZeroMemory(&wp, sizeof(wp));
duke@0 1282 wp.length = sizeof(wp);
duke@0 1283 ::GetWindowPlacement(hwnd, &wp);
duke@0 1284
duke@0 1285 // Iconify first.
duke@0 1286 // If both iconify & zoom are TRUE, handle this case
duke@0 1287 // with wp.flags field below.
duke@0 1288 if (iconify) {
duke@0 1289 wp.showCmd = focusable ? SW_MINIMIZE : SW_SHOWMINNOACTIVE;
duke@0 1290 } else if (zoom) {
duke@0 1291 wp.showCmd = focusable ? SW_SHOWMAXIMIZED : SW_MAXIMIZE;
duke@0 1292 } else { // zoom == iconify == FALSE
duke@0 1293 wp.showCmd = focusable ? SW_RESTORE : SW_SHOWNOACTIVATE;
duke@0 1294 }
duke@0 1295
duke@0 1296 if (zoom && iconify) {
duke@0 1297 wp.flags |= WPF_RESTORETOMAXIMIZED;
duke@0 1298 } else {
duke@0 1299 wp.flags &= ~WPF_RESTORETOMAXIMIZED;
duke@0 1300 }
duke@0 1301
duke@0 1302 if (!zoom) {
duke@0 1303 f->m_forceResetZoomed = TRUE;
duke@0 1304 }
duke@0 1305
duke@0 1306 // The SetWindowPlacement() causes the WmSize() invocation
duke@0 1307 // which, in turn, actually updates the m_iconic & m_zoomed flags
duke@0 1308 // as well as sends Java event (WINDOW_STATE_CHANGED.)
duke@0 1309 ::SetWindowPlacement(hwnd, &wp);
duke@0 1310
duke@0 1311 f->m_forceResetZoomed = FALSE;
duke@0 1312 } else {
duke@0 1313 DTRACE_PRINTLN(" not visible, just recording the requested state");
duke@0 1314
duke@0 1315 f->setIconic(iconify);
duke@0 1316 f->setZoomed(zoom);
duke@0 1317 }
duke@0 1318 }
duke@0 1319 ret:
duke@0 1320 env->DeleteGlobalRef(self);
duke@0 1321
duke@0 1322 delete sss;
duke@0 1323 }
duke@0 1324
duke@0 1325 jint AwtFrame::_GetState(void *param)
duke@0 1326 {
duke@0 1327 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
duke@0 1328
duke@0 1329 jobject self = (jobject)param;
duke@0 1330
duke@0 1331 jint result = java_awt_Frame_NORMAL;
duke@0 1332 AwtFrame *f = NULL;
duke@0 1333
duke@0 1334 PDATA pData;
duke@0 1335 JNI_CHECK_PEER_GOTO(self, ret);
duke@0 1336 f = (AwtFrame *)pData;
duke@0 1337 if (::IsWindow(f->GetHWnd()))
duke@0 1338 {
duke@0 1339 DASSERT(!::IsBadReadPtr(f, sizeof(AwtFrame)));
duke@0 1340 if (f->isIconic()) {
duke@0 1341 result |= java_awt_Frame_ICONIFIED;
duke@0 1342 }
duke@0 1343 if (f->isZoomed()) {
duke@0 1344 result |= java_awt_Frame_MAXIMIZED_BOTH;
duke@0 1345 }
duke@0 1346
duke@0 1347 DTRACE_PRINTLN2("WFramePeer.getState:%s%s",
duke@0 1348 f->isIconic() ? " iconic" : "",
duke@0 1349 f->isZoomed() ? " zoomed" : "");
duke@0 1350 }
duke@0 1351 ret:
duke@0 1352 env->DeleteGlobalRef(self);
duke@0 1353
duke@0 1354 return result;
duke@0 1355 }
duke@0 1356
duke@0 1357 void AwtFrame::_SetMaximizedBounds(void *param)
duke@0 1358 {
duke@0 1359 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
duke@0 1360
duke@0 1361 SetMaximizedBoundsStruct *smbs = (SetMaximizedBoundsStruct *)param;
duke@0 1362 jobject self = smbs->frame;
duke@0 1363 int x = smbs->x;
duke@0 1364 int y = smbs->y;
duke@0 1365 int width = smbs->width;
duke@0 1366 int height = smbs->height;
duke@0 1367
duke@0 1368 AwtFrame *f = NULL;
duke@0 1369
duke@0 1370 PDATA pData;
duke@0 1371 JNI_CHECK_PEER_GOTO(self, ret);
duke@0 1372 f = (AwtFrame *)pData;
duke@0 1373 if (::IsWindow(f->GetHWnd()))
duke@0 1374 {
duke@0 1375 DASSERT(!::IsBadReadPtr(f, sizeof(AwtFrame)));
duke@0 1376 f->SetMaximizedBounds(x, y, width, height);
duke@0 1377 }
duke@0 1378 ret:
duke@0 1379 env->DeleteGlobalRef(self);
duke@0 1380
duke@0 1381 delete smbs;
duke@0 1382 }
duke@0 1383
duke@0 1384 void AwtFrame::_ClearMaximizedBounds(void *param)
duke@0 1385 {
duke@0 1386 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
duke@0 1387
duke@0 1388 jobject self = (jobject)param;
duke@0 1389
duke@0 1390 AwtFrame *f = NULL;
duke@0 1391
duke@0 1392 PDATA pData;
duke@0 1393 JNI_CHECK_PEER_GOTO(self, ret);
duke@0 1394 f = (AwtFrame *)pData;
duke@0 1395 if (::IsWindow(f->GetHWnd()))
duke@0 1396 {
duke@0 1397 DASSERT(!::IsBadReadPtr(f, sizeof(AwtFrame)));
duke@0 1398 f->ClearMaximizedBounds();
duke@0 1399 }
duke@0 1400 ret:
duke@0 1401 env->DeleteGlobalRef(self);
duke@0 1402 }
duke@0 1403
duke@0 1404 void AwtFrame::_SetMenuBar(void *param)
duke@0 1405 {
duke@0 1406 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
duke@0 1407
duke@0 1408 SetMenuBarStruct *smbs = (SetMenuBarStruct *)param;
duke@0 1409 jobject self = smbs->frame;
duke@0 1410 jobject menubar = smbs->menubar;
duke@0 1411
duke@0 1412 AwtFrame *f = NULL;
duke@0 1413
duke@0 1414 PDATA pData;
duke@0 1415 JNI_CHECK_PEER_GOTO(self, ret);
duke@0 1416 f = (AwtFrame *)pData;
duke@0 1417 if (::IsWindow(f->GetHWnd()))
duke@0 1418 {
duke@0 1419 ExecuteArgs args;
duke@0 1420 args.cmdId = FRAME_SETMENUBAR;
duke@0 1421 args.param1 = (LPARAM)menubar;
duke@0 1422 f->WinThreadExecProc(&args);
duke@0 1423 }
duke@0 1424 ret:
duke@0 1425 env->DeleteGlobalRef(self);
duke@0 1426 env->DeleteGlobalRef(menubar);
duke@0 1427
duke@0 1428 delete smbs;
duke@0 1429 }
duke@0 1430
duke@0 1431 void AwtFrame::_SetIMMOption(void *param)
duke@0 1432 {
duke@0 1433 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
duke@0 1434
duke@0 1435 SetIMMOptionStruct *sios = (SetIMMOptionStruct *)param;
duke@0 1436 jobject self = sios->frame;
duke@0 1437 jstring option = sios->option;
duke@0 1438
duke@0 1439 int badAlloc = 0;
duke@0 1440 LPCTSTR coption;
art@862 1441 LPCTSTR empty = TEXT("InputMethod");
duke@0 1442 AwtFrame *f = NULL;
duke@0 1443
duke@0 1444 PDATA pData;
duke@0 1445 JNI_CHECK_PEER_GOTO(self, ret);
duke@0 1446 JNI_CHECK_NULL_GOTO(option, "IMMOption argument", ret);
duke@0 1447
duke@0 1448 f = (AwtFrame *)pData;
duke@0 1449 if (::IsWindow(f->GetHWnd()))
duke@0 1450 {
duke@0 1451 coption = JNU_GetStringPlatformChars(env, option, NULL);
duke@0 1452 if (coption == NULL)
duke@0 1453 {
duke@0 1454 badAlloc = 1;
duke@0 1455 }
duke@0 1456 if (!badAlloc)
duke@0 1457 {
duke@0 1458 HMENU hSysMenu = ::GetSystemMenu(f->GetHWnd(), FALSE);
duke@0 1459 ::AppendMenu(hSysMenu, MF_STRING, SYSCOMMAND_IMM, coption);
duke@0 1460
duke@0 1461 if (coption != empty)
duke@0 1462 {
duke@0 1463 JNU_ReleaseStringPlatformChars(env, option, coption);
duke@0 1464 }
duke@0 1465 }
duke@0 1466 }
duke@0 1467 ret:
duke@0 1468 env->DeleteGlobalRef(self);
duke@0 1469 env->DeleteGlobalRef(option);
duke@0 1470
duke@0 1471 delete sios;
duke@0 1472
duke@0 1473 if (badAlloc)
duke@0 1474 {
duke@0 1475 throw std::bad_alloc();
duke@0 1476 }
duke@0 1477 }
duke@0 1478
duke@0 1479 void AwtFrame::_NotifyModalBlocked(void *param)
duke@0 1480 {
duke@0 1481 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
duke@0 1482
duke@0 1483 NotifyModalBlockedStruct *nmbs = (NotifyModalBlockedStruct *)param;
duke@0 1484 jobject self = nmbs->frame;
duke@0 1485 jobject peer = nmbs->peer;
duke@0 1486 jobject blockerPeer = nmbs->blockerPeer;
duke@0 1487 jboolean blocked = nmbs->blocked;
duke@0 1488
duke@0 1489 PDATA pData;
duke@0 1490
duke@0 1491 pData = JNI_GET_PDATA(peer);
duke@0 1492 AwtFrame *f = (AwtFrame *)pData;
duke@0 1493
duke@0 1494 // dialog here may be NULL, for example, if the blocker is a native dialog
duke@0 1495 // however, we need to install/unistall modal hooks anyway
duke@0 1496 pData = JNI_GET_PDATA(blockerPeer);
duke@0 1497 AwtDialog *d = (AwtDialog *)pData;
duke@0 1498
duke@0 1499 if ((f != NULL) && ::IsWindow(f->GetHWnd()))
duke@0 1500 {
duke@0 1501 // get an HWND of the toplevel window this embedded frame is within
duke@0 1502 HWND fHWnd = f->GetHWnd();
duke@0 1503 while (::GetParent(fHWnd) != NULL) {
duke@0 1504 fHWnd = ::GetParent(fHWnd);
duke@0 1505 }
duke@0 1506 // we must get a toplevel hwnd here, however due to some strange
duke@0 1507 // behaviour of Java Plugin (a bug?) when running in IE at
duke@0 1508 // this moment the embedded frame hasn't been placed into the
duke@0 1509 // browser yet and fHWnd is not a toplevel, so we shouldn't install
duke@0 1510 // the hook here
duke@0 1511 if ((::GetWindowLong(fHWnd, GWL_STYLE) & WS_CHILD) == 0) {
duke@0 1512 // if this toplevel is created in another thread, we should install
duke@0 1513 // the modal hook into it to track window activation and mouse events
duke@0 1514 DWORD fThread = ::GetWindowThreadProcessId(fHWnd, NULL);
duke@0 1515 if (fThread != AwtToolkit::GetInstance().MainThread()) {
duke@0 1516 // check if this thread has been already blocked
duke@0 1517 BlockedThreadStruct *blockedThread = (BlockedThreadStruct *)sm_BlockedThreads.get((void *)fThread);
duke@0 1518 if (blocked) {
duke@0 1519 if (blockedThread == NULL) {
duke@0 1520 blockedThread = new BlockedThreadStruct;
duke@0 1521 blockedThread->framesCount = 1;
duke@0 1522 blockedThread->modalHook = ::SetWindowsHookEx(WH_CBT, (HOOKPROC)AwtDialog::ModalFilterProc,
duke@0 1523 0, fThread);
duke@0 1524 blockedThread->mouseHook = ::SetWindowsHookEx(WH_MOUSE, (HOOKPROC)AwtDialog::MouseHookProc_NonTT,
duke@0 1525 0, fThread);
duke@0 1526 sm_BlockedThreads.put((void *)fThread, blockedThread);
duke@0 1527 } else {
duke@0 1528 blockedThread->framesCount++;
duke@0 1529 }
duke@0 1530 } else {
duke@0 1531 // see the comment above: if Java Plugin behaviour when running in IE
duke@0 1532 // was right, blockedThread would be always not NULL here
duke@0 1533 if (blockedThread != NULL) {
duke@0 1534 DASSERT(blockedThread->framesCount > 0);
duke@0 1535 if ((blockedThread->framesCount) == 1) {
duke@0 1536 ::UnhookWindowsHookEx(blockedThread->modalHook);
duke@0 1537 ::UnhookWindowsHookEx(blockedThread->mouseHook);
duke@0 1538 sm_BlockedThreads.remove((void *)fThread);
duke@0 1539 delete blockedThread;
duke@0 1540 } else {
duke@0 1541 blockedThread->framesCount--;
duke@0 1542 }
duke@0 1543 }
duke@0 1544 }
duke@0 1545 }
duke@0 1546 }
duke@0 1547 }
duke@0 1548
duke@0 1549 env->DeleteGlobalRef(self);
duke@0 1550 env->DeleteGlobalRef(peer);
duke@0 1551 env->DeleteGlobalRef(blockerPeer);
duke@0 1552
duke@0 1553 delete nmbs;
duke@0 1554 }
duke@0 1555
duke@0 1556 /************************************************************************
duke@0 1557 * WFramePeer native methods
duke@0 1558 */
duke@0 1559
duke@0 1560 extern "C" {
duke@0 1561
duke@0 1562 /*
dcherepanov@1047 1563 * Class: java_awt_Frame
duke@0 1564 * Method: initIDs
duke@0 1565 * Signature: ()V
duke@0 1566 */
duke@0 1567 JNIEXPORT void JNICALL
duke@0 1568 Java_java_awt_Frame_initIDs(JNIEnv *env, jclass cls)
duke@0 1569 {
duke@0 1570 TRY;
duke@0 1571
duke@0 1572 AwtFrame::undecoratedID = env->GetFieldID(cls,"undecorated","Z");
duke@0 1573 DASSERT(AwtFrame::undecoratedID != NULL);
duke@0 1574
duke@0 1575 CATCH_BAD_ALLOC;
duke@0 1576 }
duke@0 1577
duke@0 1578 /*
duke@0 1579 * Class: sun_awt_windows_WFramePeer
dcherepanov@1047 1580 * Method: initIDs
dcherepanov@1047 1581 * Signature: ()V
dcherepanov@1047 1582 */
dcherepanov@1047 1583 JNIEXPORT void JNICALL
dcherepanov@1047 1584 Java_sun_awt_windows_WFramePeer_initIDs(JNIEnv *env, jclass cls)
dcherepanov@1047 1585 {
dcherepanov@1047 1586 TRY;
dcherepanov@1047 1587
dcherepanov@1047 1588 AwtFrame::setExtendedStateMID = env->GetMethodID(cls, "setExtendedState", "(I)V");
dcherepanov@1047 1589 AwtFrame::getExtendedStateMID = env->GetMethodID(cls, "getExtendedState", "()I");
dcherepanov@1047 1590
dcherepanov@1047 1591 DASSERT(AwtFrame::setExtendedStateMID);
dcherepanov@1047 1592 DASSERT(AwtFrame::getExtendedStateMID);
dcherepanov@1047 1593
dcherepanov@1047 1594 CATCH_BAD_ALLOC;
dcherepanov@1047 1595 }
dcherepanov@1047 1596
dcherepanov@1047 1597 /*
dcherepanov@1047 1598 * Class: sun_awt_windows_WFramePeer
duke@0 1599 * Method: setState
duke@0 1600 * Signature: (I)V
duke@0 1601 */
duke@0 1602 JNIEXPORT void JNICALL
duke@0 1603 Java_sun_awt_windows_WFramePeer_setState(JNIEnv *env, jobject self,
duke@0 1604 jint state)
duke@0 1605 {
duke@0 1606 TRY;
duke@0 1607
duke@0 1608 SetStateStruct *sss = new SetStateStruct;
duke@0 1609 sss->frame = env->NewGlobalRef(self);
duke@0 1610 sss->state = state;
duke@0 1611
duke@0 1612 AwtToolkit::GetInstance().SyncCall(AwtFrame::_SetState, sss);
duke@0 1613 // global ref and sss are deleted in _SetState()
duke@0 1614
duke@0 1615 CATCH_BAD_ALLOC;
duke@0 1616 }
duke@0 1617
duke@0 1618 /*
duke@0 1619 * Class: sun_awt_windows_WFramePeer
duke@0 1620 * Method: getState
duke@0 1621 * Signature: ()I
duke@0 1622 */
duke@0 1623 JNIEXPORT jint JNICALL
duke@0 1624 Java_sun_awt_windows_WFramePeer_getState(JNIEnv *env, jobject self)
duke@0 1625 {
duke@0 1626 TRY;
duke@0 1627
duke@0 1628 jobject selfGlobalRef = env->NewGlobalRef(self);
duke@0 1629
duke@0 1630 return static_cast<jint>(reinterpret_cast<INT_PTR>(AwtToolkit::GetInstance().SyncCall(
duke@0 1631 (void*(*)(void*))AwtFrame::_GetState,
duke@0 1632 (void *)selfGlobalRef)));
duke@0 1633 // selfGlobalRef is deleted in _GetState()
duke@0 1634
duke@0 1635 CATCH_BAD_ALLOC_RET(java_awt_Frame_NORMAL);
duke@0 1636 }
duke@0 1637
duke@0 1638
duke@0 1639 /*
duke@0 1640 * Class: sun_awt_windows_WFramePeer
duke@0 1641 * Method: setMaximizedBounds
duke@0 1642 * Signature: (IIII)V
duke@0 1643 */
duke@0 1644 JNIEXPORT void JNICALL
duke@0 1645 Java_sun_awt_windows_WFramePeer_setMaximizedBounds(JNIEnv *env, jobject self,
duke@0 1646 jint x, jint y, jint width, jint height)
duke@0 1647 {
duke@0 1648 TRY;
duke@0 1649
duke@0 1650 SetMaximizedBoundsStruct *smbs = new SetMaximizedBoundsStruct;
duke@0 1651 smbs->frame = env->NewGlobalRef(self);
duke@0 1652 smbs->x = x;
duke@0 1653 smbs->y = y;
duke@0 1654 smbs->width = width;
duke@0 1655 smbs->height = height;
duke@0 1656
duke@0 1657 AwtToolkit::GetInstance().SyncCall(AwtFrame::_SetMaximizedBounds, smbs);
duke@0 1658 // global ref and smbs are deleted in _SetMaximizedBounds()
duke@0 1659
duke@0 1660 CATCH_BAD_ALLOC;
duke@0 1661 }
duke@0 1662
duke@0 1663
duke@0 1664 /*
duke@0 1665 * Class: sun_awt_windows_WFramePeer
duke@0 1666 * Method: clearMaximizedBounds
duke@0 1667 * Signature: ()V
duke@0 1668 */
duke@0 1669 JNIEXPORT void JNICALL
duke@0 1670 Java_sun_awt_windows_WFramePeer_clearMaximizedBounds(JNIEnv *env, jobject self)
duke@0 1671 {
duke@0 1672 TRY;
duke@0 1673
duke@0 1674 jobject selfGlobalRef = env->NewGlobalRef(self);
duke@0 1675
duke@0 1676 AwtToolkit::GetInstance().SyncCall(AwtFrame::_ClearMaximizedBounds,
duke@0 1677 (void *)selfGlobalRef);
duke@0 1678 // selfGlobalRef is deleted in _ClearMaximizedBounds()
duke@0 1679
duke@0 1680 CATCH_BAD_ALLOC;
duke@0 1681 }
duke@0 1682
duke@0 1683
duke@0 1684 /*
duke@0 1685 * Class: sun_awt_windows_WFramePeer
duke@0 1686 * Method: setMenuBar0
duke@0 1687 * Signature: (Lsun/awt/windows/WMenuBarPeer;)V
duke@0 1688 */
duke@0 1689 JNIEXPORT void JNICALL
duke@0 1690 Java_sun_awt_windows_WFramePeer_setMenuBar0(JNIEnv *env, jobject self,
duke@0 1691 jobject mbPeer)
duke@0 1692 {
duke@0 1693 TRY;
duke@0 1694
duke@0 1695 SetMenuBarStruct *smbs = new SetMenuBarStruct;
duke@0 1696 smbs->frame = env->NewGlobalRef(self);
duke@0 1697 smbs->menubar = env->NewGlobalRef(mbPeer);
duke@0 1698
duke@0 1699 AwtToolkit::GetInstance().SyncCall(AwtFrame::_SetMenuBar, smbs);
duke@0 1700 // global refs ans smbs are deleted in _SetMenuBar()
duke@0 1701
duke@0 1702 CATCH_BAD_ALLOC;
duke@0 1703 }
duke@0 1704
duke@0 1705 /*
duke@0 1706 * Class: sun_awt_windows_WFramePeer
duke@0 1707 * Method: create
duke@0 1708 * Signature: (Lsun/awt/windows/WComponentPeer;)V
duke@0 1709 */
duke@0 1710 JNIEXPORT void JNICALL
duke@0 1711 Java_sun_awt_windows_WFramePeer_createAwtFrame(JNIEnv *env, jobject self,
duke@0 1712 jobject parent)
duke@0 1713 {
duke@0 1714 TRY;
duke@0 1715
duke@0 1716 AwtToolkit::CreateComponent(self, parent,
duke@0 1717 (AwtToolkit::ComponentFactory)
duke@0 1718 AwtFrame::Create);
duke@0 1719 PDATA pData;
duke@0 1720 JNI_CHECK_PEER_CREATION_RETURN(self);
duke@0 1721
duke@0 1722 CATCH_BAD_ALLOC;
duke@0 1723 }
duke@0 1724
duke@0 1725 /*
duke@0 1726 * Class: sun_awt_windows_WFramePeer
duke@0 1727 * Method: getSysMenuHeight
duke@0 1728 * Signature: ()I
duke@0 1729 */
duke@0 1730 JNIEXPORT jint JNICALL
duke@0 1731 Java_sun_awt_windows_WFramePeer_getSysMenuHeight(JNIEnv *env, jclass self)
duke@0 1732 {
duke@0 1733 TRY;
duke@0 1734
duke@0 1735 return ::GetSystemMetrics(SM_CYMENUSIZE);
duke@0 1736
duke@0 1737 CATCH_BAD_ALLOC_RET(0);
duke@0 1738 }
duke@0 1739
duke@0 1740 /*
duke@0 1741 * Class: sun_awt_windows_WFramePeer
duke@0 1742 * Method: pSetIMMOption
duke@0 1743 * Signature: (Ljava/lang/String;)V
duke@0 1744 */
duke@0 1745 JNIEXPORT void JNICALL
duke@0 1746 Java_sun_awt_windows_WFramePeer_pSetIMMOption(JNIEnv *env, jobject self,
duke@0 1747 jstring option)
duke@0 1748 {
duke@0 1749 TRY;
duke@0 1750
duke@0 1751 SetIMMOptionStruct *sios = new SetIMMOptionStruct;
duke@0 1752 sios->frame = env->NewGlobalRef(self);
duke@0 1753 sios->option = (jstring)env->NewGlobalRef(option);
duke@0 1754
duke@0 1755 AwtToolkit::GetInstance().SyncCall(AwtFrame::_SetIMMOption, sios);
duke@0 1756 // global refs and sios are deleted in _SetIMMOption()
duke@0 1757
duke@0 1758 CATCH_BAD_ALLOC;
duke@0 1759 }
duke@0 1760
duke@0 1761 } /* extern "C" */
duke@0 1762
duke@0 1763
duke@0 1764 /************************************************************************
duke@0 1765 * EmbeddedFrame native methods
duke@0 1766 */
duke@0 1767
duke@0 1768 extern "C" {
duke@0 1769
duke@0 1770 /*
duke@0 1771 * Class: sun_awt_EmbeddedFrame
duke@0 1772 * Method: setPeer
duke@0 1773 * Signature: (Ljava/awt/peer/ComponentPeer;)V
duke@0 1774 */
duke@0 1775 JNIEXPORT void JNICALL
duke@0 1776 Java_sun_awt_EmbeddedFrame_setPeer(JNIEnv *env, jobject self, jobject lpeer)
duke@0 1777 {
duke@0 1778 TRY;
duke@0 1779
duke@0 1780 jclass cls;
duke@0 1781 jfieldID fid;
duke@0 1782
duke@0 1783 cls = env->GetObjectClass(self);
duke@0 1784 fid = env->GetFieldID(cls, "peer", "Ljava/awt/peer/ComponentPeer;");
duke@0 1785 env->SetObjectField(self, fid, lpeer);
duke@0 1786
duke@0 1787 CATCH_BAD_ALLOC;
duke@0 1788 }
duke@0 1789
duke@0 1790 } /* extern "C" */
duke@0 1791
duke@0 1792
duke@0 1793 /************************************************************************
duke@0 1794 * WEmbeddedFrame native methods
duke@0 1795 */
duke@0 1796
duke@0 1797 extern "C" {
duke@0 1798
duke@0 1799 /*
duke@0 1800 * Class: sun_awt_windows_WFramePeer
duke@0 1801 * Method: initIDs
duke@0 1802 * Signature: (Lsun/awt/windows/WMenuBarPeer;)V
duke@0 1803 */
duke@0 1804 JNIEXPORT void JNICALL
duke@0 1805 Java_sun_awt_windows_WEmbeddedFrame_initIDs(JNIEnv *env, jclass cls)
duke@0 1806 {
duke@0 1807 TRY;
duke@0 1808
duke@0 1809 AwtFrame::handleID = env->GetFieldID(cls, "handle", "J");
duke@0 1810 DASSERT(AwtFrame::handleID != NULL);
duke@0 1811
duke@0 1812 AwtFrame::activateEmbeddingTopLevelMID = env->GetMethodID(cls, "activateEmbeddingTopLevel", "()V");
duke@0 1813 DASSERT(AwtFrame::activateEmbeddingTopLevelMID != NULL);
duke@0 1814
duke@0 1815 CATCH_BAD_ALLOC;
duke@0 1816 }
duke@0 1817
duke@0 1818 JNIEXPORT void JNICALL
duke@0 1819 Java_sun_awt_windows_WEmbeddedFrame_notifyModalBlockedImpl(JNIEnv *env,
duke@0 1820 jobject self,
duke@0 1821 jobject peer,
duke@0 1822 jobject blockerPeer,
duke@0 1823 jboolean blocked)
duke@0 1824 {
duke@0 1825 TRY;
duke@0 1826
duke@0 1827 NotifyModalBlockedStruct *nmbs = new NotifyModalBlockedStruct;
duke@0 1828 nmbs->frame = env->NewGlobalRef(self);
duke@0 1829 nmbs->peer = env->NewGlobalRef(peer);
duke@0 1830 nmbs->blockerPeer = env->NewGlobalRef(blockerPeer);
duke@0 1831 nmbs->blocked = blocked;
duke@0 1832
duke@0 1833 AwtToolkit::GetInstance().SyncCall(AwtFrame::_NotifyModalBlocked, nmbs);
duke@0 1834 // global refs and nmbs are deleted in _NotifyModalBlocked()
duke@0 1835
duke@0 1836 CATCH_BAD_ALLOC;
duke@0 1837 }
duke@0 1838
duke@0 1839 } /* extern "C" */
duke@0 1840
duke@0 1841
duke@0 1842 /************************************************************************
duke@0 1843 * WEmbeddedFramePeer native methods
duke@0 1844 */
duke@0 1845
duke@0 1846 extern "C" {
duke@0 1847
duke@0 1848 JNIEXPORT void JNICALL
duke@0 1849 Java_sun_awt_windows_WEmbeddedFramePeer_create(JNIEnv *env, jobject self,
duke@0 1850 jobject parent)
duke@0 1851 {
duke@0 1852 TRY;
duke@0 1853
duke@0 1854 JNI_CHECK_NULL_RETURN(self, "peer");
duke@0 1855 AwtToolkit::CreateComponent(self, parent,
duke@0 1856 (AwtToolkit::ComponentFactory)
duke@0 1857 AwtFrame::Create);
duke@0 1858 PDATA pData;
duke@0 1859 JNI_CHECK_PEER_CREATION_RETURN(self);
duke@0 1860
duke@0 1861 CATCH_BAD_ALLOC;
duke@0 1862 }
duke@0 1863
duke@0 1864 JNIEXPORT jobject JNICALL
duke@0 1865 Java_sun_awt_windows_WEmbeddedFramePeer_getBoundsPrivate(JNIEnv *env, jobject self)
duke@0 1866 {
duke@0 1867 TRY;
duke@0 1868
duke@0 1869 jobject result = (jobject)AwtToolkit::GetInstance().SyncCall(
duke@0 1870 (void *(*)(void *))AwtFrame::_GetBoundsPrivate,
duke@0 1871 env->NewGlobalRef(self));
duke@0 1872 // global ref is deleted in _GetBoundsPrivate
duke@0 1873
duke@0 1874 if (result != NULL)
duke@0 1875 {
duke@0 1876 jobject resultLocalRef = env->NewLocalRef(result);
duke@0 1877 env->DeleteGlobalRef(result);
duke@0 1878 return resultLocalRef;
duke@0 1879 }
duke@0 1880 else
duke@0 1881 {
duke@0 1882 return NULL;
duke@0 1883 }
duke@0 1884
duke@0 1885 CATCH_BAD_ALLOC_RET(NULL);
duke@0 1886 }
duke@0 1887
duke@0 1888 JNIEXPORT void JNICALL
duke@0 1889 Java_sun_awt_windows_WEmbeddedFramePeer_synthesizeWmActivate(JNIEnv *env, jobject self, jboolean doActivate)
duke@0 1890 {
duke@0 1891 TRY;
duke@0 1892
duke@0 1893 SynthesizeWmActivateStruct *sas = new SynthesizeWmActivateStruct;
duke@0 1894 sas->frame = env->NewGlobalRef(self);
duke@0 1895 sas->doActivate = doActivate;
duke@0 1896
duke@0 1897 /*
duke@0 1898 * WARNING: invoking this function without synchronization by m_Sync CriticalSection.
duke@0 1899 * Taking this lock results in a deadlock.
duke@0 1900 */
duke@0 1901 AwtToolkit::GetInstance().InvokeFunction(AwtFrame::_SynthesizeWmActivate, sas);
duke@0 1902 // global ref and sas are deleted in _SynthesizeWmActivate()
duke@0 1903
duke@0 1904 CATCH_BAD_ALLOC;
duke@0 1905 }
duke@0 1906
duke@0 1907 } /* extern "C" */