1 /* 2 * Copyright (c) 1996, 2010, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 #include "awt.h" 27 28 #include <windowsx.h> 29 #include <zmouse.h> 30 31 #include "jlong.h" 32 #include "awt_AWTEvent.h" 33 #include "awt_BitmapUtil.h" 34 #include "awt_Component.h" 35 #include "awt_Cursor.h" 36 #include "awt_Dimension.h" 37 #include "awt_Frame.h" 38 #include "awt_InputEvent.h" 39 #include "awt_InputTextInfor.h" 40 #include "awt_Insets.h" 41 #include "awt_KeyEvent.h" 42 #include "awt_MenuItem.h" 43 #include "awt_MouseEvent.h" 44 #include "awt_Palette.h" 45 #include "awt_Toolkit.h" 46 #include "awt_Window.h" 47 #include "awt_Win32GraphicsDevice.h" 48 #include "Hashtable.h" 49 #include "ComCtl32Util.h" 50 51 #include <Region.h> 52 53 #include <jawt.h> 54 55 #include <java_awt_Toolkit.h> 56 #include <java_awt_FontMetrics.h> 57 #include <java_awt_Color.h> 58 #include <java_awt_Event.h> 59 #include <java_awt_event_KeyEvent.h> 60 #include <java_awt_Insets.h> 61 #include <sun_awt_windows_WPanelPeer.h> 62 #include <java_awt_event_InputEvent.h> 63 #include <java_awt_event_InputMethodEvent.h> 64 #include <sun_awt_windows_WInputMethod.h> 65 #include <java_awt_event_MouseEvent.h> 66 #include <java_awt_event_MouseWheelEvent.h> 67 68 // Begin -- Win32 SDK include files 69 #include <imm.h> 70 #include <ime.h> 71 // End -- Win32 SDK include files 72 73 #include <awt_DnDDT.h> 74 75 LPCTSTR szAwtComponentClassName = TEXT("SunAwtComponent"); 76 // register a message that no other window in the process (even in a plugin 77 // scenario) will be using 78 const UINT AwtComponent::WmAwtIsComponent = 79 ::RegisterWindowMessage(szAwtComponentClassName); 80 81 static HWND g_hwndDown = NULL; 82 static DCList activeDCList; 83 static DCList passiveDCList; 84 85 extern void CheckFontSmoothingSettings(HWND); 86 87 extern "C" { 88 // Remember the input language has changed by some user's action 89 // (Alt+Shift or through the language icon on the Taskbar) to control the 90 // race condition between the toolkit thread and the AWT event thread. 91 // This flag remains TRUE until the next WInputMethod.getNativeLocale() is 92 // issued. 93 BOOL g_bUserHasChangedInputLang = FALSE; 94 } 95 96 BOOL AwtComponent::sm_suppressFocusAndActivation = FALSE; 97 BOOL AwtComponent::sm_restoreFocusAndActivation = FALSE; 98 HWND AwtComponent::sm_focusOwner = NULL; 99 HWND AwtComponent::sm_focusedWindow = NULL; 100 BOOL AwtComponent::sm_bMenuLoop = FALSE; 101 AwtComponent* AwtComponent::sm_getComponentCache = NULL; 102 BOOL AwtComponent::sm_inSynthesizeFocus = FALSE; 103 104 /************************************************************************/ 105 // Struct for _Reshape() and ReshapeNoCheck() methods 106 struct ReshapeStruct { 107 jobject component; 108 jint x, y; 109 jint w, h; 110 }; 111 // Struct for _NativeHandleEvent() method 112 struct NativeHandleEventStruct { 113 jobject component; 114 jobject event; 115 }; 116 // Struct for _SetForeground() and _SetBackground() methods 117 struct SetColorStruct { 118 jobject component; 119 jint rgb; 120 }; 121 // Struct for _SetFont() method 122 struct SetFontStruct { 123 jobject component; 124 jobject font; 125 }; 126 // Struct for _CreatePrintedPixels() method 127 struct CreatePrintedPixelsStruct { 128 jobject component; 129 int srcx, srcy; 130 int srcw, srch; 131 jint alpha; 132 }; 133 // Struct for _SetRectangularShape() method 134 struct SetRectangularShapeStruct { 135 jobject component; 136 jint x1, x2, y1, y2; 137 jobject region; 138 }; 139 // Struct for _GetInsets function 140 struct GetInsetsStruct { 141 jobject window; 142 RECT *insets; 143 }; 144 // Struct for _SetZOrder function 145 struct SetZOrderStruct { 146 jobject component; 147 jlong above; 148 }; 149 // Struct for _SetFocus function 150 struct SetFocusStruct { 151 jobject component; 152 jboolean doSetFocus; 153 }; 154 /************************************************************************/ 155 156 ////////////////////////////////////////////////////////////////////////// 157 158 /************************************************************************* 159 * AwtComponent fields 160 */ 161 162 163 jfieldID AwtComponent::peerID; 164 jfieldID AwtComponent::xID; 165 jfieldID AwtComponent::yID; 166 jfieldID AwtComponent::widthID; 167 jfieldID AwtComponent::heightID; 168 jfieldID AwtComponent::visibleID; 169 jfieldID AwtComponent::backgroundID; 170 jfieldID AwtComponent::foregroundID; 171 jfieldID AwtComponent::enabledID; 172 jfieldID AwtComponent::parentID; 173 jfieldID AwtComponent::graphicsConfigID; 174 jfieldID AwtComponent::peerGCID; 175 jfieldID AwtComponent::focusableID; 176 jfieldID AwtComponent::appContextID; 177 jfieldID AwtComponent::cursorID; 178 jfieldID AwtComponent::hwndID; 179 180 jmethodID AwtComponent::getFontMID; 181 jmethodID AwtComponent::getToolkitMID; 182 jmethodID AwtComponent::isEnabledMID; 183 jmethodID AwtComponent::getLocationOnScreenMID; 184 jmethodID AwtComponent::replaceSurfaceDataMID; 185 jmethodID AwtComponent::replaceSurfaceDataLaterMID; 186 jmethodID AwtComponent::disposeLaterMID; 187 188 HKL AwtComponent::m_hkl = ::GetKeyboardLayout(0); 189 LANGID AwtComponent::m_idLang = LOWORD(::GetKeyboardLayout(0)); 190 UINT AwtComponent::m_CodePage 191 = AwtComponent::LangToCodePage(m_idLang); 192 193 jint *AwtComponent::masks; 194 195 static BOOL bLeftShiftIsDown = false; 196 static BOOL bRightShiftIsDown = false; 197 static UINT lastShiftKeyPressed = 0; // init to safe value 198 199 // Added by waleed to initialize the RTL Flags 200 BOOL AwtComponent::sm_rtl = PRIMARYLANGID(GetInputLanguage()) == LANG_ARABIC || 201 PRIMARYLANGID(GetInputLanguage()) == LANG_HEBREW; 202 BOOL AwtComponent::sm_rtlReadingOrder = 203 PRIMARYLANGID(GetInputLanguage()) == LANG_ARABIC; 204 205 BOOL AwtComponent::sm_PrimaryDynamicTableBuilt = FALSE; 206 207 HWND AwtComponent::sm_cursorOn; 208 BOOL AwtComponent::m_QueryNewPaletteCalled = FALSE; 209 210 CriticalSection windowMoveLock; 211 BOOL windowMoveLockHeld = FALSE; 212 213 /************************************************************************ 214 * AwtComponent methods 215 */ 216 217 AwtComponent::AwtComponent() 218 { 219 m_mouseButtonClickAllowed = 0; 220 m_callbacksEnabled = FALSE; 221 m_hwnd = NULL; 222 223 m_colorForeground = 0; 224 m_colorBackground = 0; 225 m_backgroundColorSet = FALSE; 226 m_penForeground = NULL; 227 m_brushBackground = NULL; 228 m_DefWindowProc = NULL; 229 m_nextControlID = 1; 230 m_childList = NULL; 231 m_myControlID = 0; 232 m_hdwp = NULL; 233 m_validationNestCount = 0; 234 235 m_dropTarget = NULL; 236 237 m_InputMethod = NULL; 238 m_useNativeCompWindow = TRUE; 239 m_PendingLeadByte = 0; 240 m_bitsCandType = 0; 241 242 windowMoveLockPosX = 0; 243 windowMoveLockPosY = 0; 244 windowMoveLockPosCX = 0; 245 windowMoveLockPosCY = 0; 246 247 m_hCursorCache = NULL; 248 249 m_bSubclassed = FALSE; 250 m_bPauseDestroy = FALSE; 251 252 m_MessagesProcessing = 0; 253 m_wheelRotationAmount = 0; 254 if (!sm_PrimaryDynamicTableBuilt) { 255 // do it once. 256 AwtComponent::BuildPrimaryDynamicTable(); 257 sm_PrimaryDynamicTableBuilt = TRUE; 258 } 259 } 260 261 AwtComponent::~AwtComponent() 262 { 263 DASSERT(AwtToolkit::IsMainThread()); 264 265 /* Disconnect all links. */ 266 UnlinkObjects(); 267 268 /* 269 * All the messages for this component are processed, native 270 * resources are freed, and Java object is not connected to 271 * the native one anymore. So we can safely destroy component's 272 * handle. 273 */ 274 DestroyHWnd(); 275 276 if (sm_getComponentCache == this) { 277 sm_getComponentCache = NULL; 278 } 279 } 280 281 void AwtComponent::Dispose() 282 { 283 // NOTE: in case the component/toplevel was focused, Java should 284 // have already taken care of proper transfering it or clearing. 285 286 if (m_hdwp != NULL) { 287 // end any deferred window positioning, regardless 288 // of m_validationNestCount 289 ::EndDeferWindowPos(m_hdwp); 290 } 291 292 // Send final message to release all DCs associated with this component 293 SendMessage(WM_AWT_RELEASE_ALL_DCS); 294 295 /* Stop message filtering. */ 296 UnsubclassHWND(); 297 298 /* Release global ref to input method */ 299 SetInputMethod(NULL, TRUE); 300 301 if (m_childList != NULL) 302 delete m_childList; 303 304 DestroyDropTarget(); 305 ReleaseDragCapture(0); 306 307 if (m_myControlID != 0) { 308 AwtComponent* parent = GetParent(); 309 if (parent != NULL) 310 parent->RemoveChild(m_myControlID); 311 } 312 313 ::RemoveProp(GetHWnd(), DrawingStateProp); 314 315 /* Release any allocated resources. */ 316 if (m_penForeground != NULL) { 317 m_penForeground->Release(); 318 m_penForeground = NULL; 319 } 320 if (m_brushBackground != NULL) { 321 m_brushBackground->Release(); 322 m_brushBackground = NULL; 323 } 324 325 if (m_bPauseDestroy) { 326 // AwtComponent::WmNcDestroy could be released now 327 m_bPauseDestroy = FALSE; 328 m_hwnd = NULL; 329 } 330 331 // The component instance is deleted using AwtObject::Dispose() method 332 AwtObject::Dispose(); 333 } 334 335 /* store component pointer in window extra bytes */ 336 void AwtComponent::SetComponentInHWND() { 337 DASSERT(::GetWindowLongPtr(GetHWnd(), GWLP_USERDATA) == NULL); 338 ::SetWindowLongPtr(GetHWnd(), GWLP_USERDATA, (LONG_PTR)this); 339 } 340 341 /* 342 * static function to get AwtComponent pointer from hWnd -- 343 * you don't want to call this from inside a wndproc to avoid 344 * infinite recursion 345 */ 346 AwtComponent* AwtComponent::GetComponent(HWND hWnd) { 347 // Requests for Toolkit hwnd resolution happen pretty often. Check first. 348 if (hWnd == AwtToolkit::GetInstance().GetHWnd()) { 349 return NULL; 350 } 351 if (sm_getComponentCache && sm_getComponentCache->GetHWnd() == hWnd) { 352 return sm_getComponentCache; 353 } 354 355 // check that it's an AWT component from the same toolkit as the caller 356 if (::IsWindow(hWnd) && 357 AwtToolkit::MainThread() == ::GetWindowThreadProcessId(hWnd, NULL)) 358 { 359 DASSERT(WmAwtIsComponent != 0); 360 if (::SendMessage(hWnd, WmAwtIsComponent, 0, 0L)) { 361 return sm_getComponentCache = GetComponentImpl(hWnd); 362 } 363 } 364 return NULL; 365 } 366 367 /* 368 * static function to get AwtComponent pointer from hWnd-- 369 * different from GetComponent because caller knows the 370 * hwnd is an AWT component hwnd 371 */ 372 AwtComponent* AwtComponent::GetComponentImpl(HWND hWnd) { 373 AwtComponent *component = 374 (AwtComponent *)::GetWindowLongPtr(hWnd, GWLP_USERDATA); 375 DASSERT(!component || !IsBadReadPtr(component, sizeof(AwtComponent)) ); 376 DASSERT(!component || component->GetHWnd() == hWnd ); 377 return component; 378 } 379 380 /* 381 * Single window proc for all the components. Delegates real work to 382 * the component's WindowProc() member function. 383 */ 384 LRESULT CALLBACK AwtComponent::WndProc(HWND hWnd, UINT message, 385 WPARAM wParam, LPARAM lParam) 386 { 387 TRY; 388 389 AwtComponent * self = AwtComponent::GetComponentImpl(hWnd); 390 if (self == NULL || self->GetHWnd() != hWnd || 391 message == WM_UNDOCUMENTED_CLIENTSHUTDOWN) // handle log-off gracefully 392 { 393 return ComCtl32Util::GetInstance().DefWindowProc(NULL, hWnd, message, wParam, lParam); 394 } else { 395 return self->WindowProc(message, wParam, lParam); 396 } 397 398 CATCH_BAD_ALLOC_RET(0); 399 } 400 401 BOOL AwtComponent::IsFocusable() { 402 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); 403 jobject peer = GetPeer(env); 404 jobject target = env->GetObjectField(peer, AwtObject::targetID); 405 BOOL res = env->GetBooleanField(target, focusableID); 406 AwtWindow *pCont = GetContainer(); 407 if (pCont) { 408 res &= pCont->IsFocusableWindow(); 409 } 410 env->DeleteLocalRef(target); 411 return res; 412 } 413 414 /************************************************************************ 415 * AwtComponent dynamic methods 416 * 417 * Window class registration routines 418 */ 419 420 /* 421 * Fix for 4964237: Win XP: Changing theme changes java dialogs title icon 422 */ 423 void AwtComponent::FillClassInfo(WNDCLASSEX *lpwc) 424 { 425 lpwc->cbSize = sizeof(WNDCLASSEX); 426 lpwc->style = 0L;//CS_OWNDC; 427 lpwc->lpfnWndProc = (WNDPROC)::DefWindowProc; 428 lpwc->cbClsExtra = 0; 429 lpwc->cbWndExtra = 0; 430 lpwc->hInstance = AwtToolkit::GetInstance().GetModuleHandle(), 431 lpwc->hIcon = AwtToolkit::GetInstance().GetAwtIcon(); 432 lpwc->hCursor = NULL; 433 lpwc->hbrBackground = NULL; 434 lpwc->lpszMenuName = NULL; 435 lpwc->lpszClassName = GetClassName(); 436 //Fixed 6233560: PIT: Java Cup Logo on the title bar of top-level windows look blurred, Win32 437 lpwc->hIconSm = AwtToolkit::GetInstance().GetAwtIconSm(); 438 } 439 440 void AwtComponent::RegisterClass() 441 { 442 WNDCLASSEX wc; 443 if (!::GetClassInfoEx(AwtToolkit::GetInstance().GetModuleHandle(), GetClassName(), &wc)) { 444 FillClassInfo(&wc); 445 ATOM ret = ::RegisterClassEx(&wc); 446 DASSERT(ret != 0); 447 } 448 } 449 450 void AwtComponent::UnregisterClass() 451 { 452 ::UnregisterClass(GetClassName(), AwtToolkit::GetInstance().GetModuleHandle()); 453 } 454 455 /* 456 * Copy the graphicsConfig reference from Component into WComponentPeer 457 */ 458 void AwtComponent::InitPeerGraphicsConfig(JNIEnv *env, jobject peer) 459 { 460 jobject target = env->GetObjectField(peer, AwtObject::targetID); 461 //Get graphicsConfig object ref from Component 462 jobject compGC = env->GetObjectField(target, 463 AwtComponent::graphicsConfigID); 464 465 //Set peer's graphicsConfig to Component's graphicsConfig 466 if (compGC != NULL) { 467 jclass win32GCCls = env->FindClass("sun/awt/Win32GraphicsConfig"); 468 DASSERT(win32GCCls != NULL); 469 DASSERT(env->IsInstanceOf(compGC, win32GCCls)); 470 env->SetObjectField(peer, AwtComponent::peerGCID, compGC); 471 } 472 } 473 474 void 475 AwtComponent::CreateHWnd(JNIEnv *env, LPCWSTR title, 476 DWORD windowStyle, 477 DWORD windowExStyle, 478 int x, int y, int w, int h, 479 HWND hWndParent, HMENU hMenu, 480 COLORREF colorForeground, 481 COLORREF colorBackground, 482 jobject peer) 483 { 484 if (env->EnsureLocalCapacity(2) < 0) { 485 return; 486 } 487 488 /* 489 * The window class of multifont label must be "BUTTON" because 490 * "STATIC" class can't get WM_DRAWITEM message, and m_peerObject 491 * member is referred in the GetClassName method of AwtLabel class. 492 * So m_peerObject member must be set here. 493 */ 494 m_peerObject = env->NewGlobalRef(peer); 495 RegisterClass(); 496 497 jobject target = env->GetObjectField(peer, AwtObject::targetID); 498 jboolean visible = env->GetBooleanField(target, AwtComponent::visibleID); 499 m_visible = visible; 500 501 if (visible) { 502 windowStyle |= WS_VISIBLE; 503 } else { 504 windowStyle &= ~WS_VISIBLE; 505 } 506 507 InitPeerGraphicsConfig(env, peer); 508 509 SetLastError(0); 510 HWND hwnd = ::CreateWindowEx(windowExStyle, 511 GetClassName(), 512 title, 513 windowStyle, 514 x, y, w, h, 515 hWndParent, 516 hMenu, 517 AwtToolkit::GetInstance().GetModuleHandle(), 518 NULL); 519 520 // fix for 5088782 521 // check if CreateWindowsEx() returns not null value and if it does - 522 // create an InternalError or OutOfMemoryError based on GetLastError(). 523 // This error is set to createError field of WObjectPeer and then 524 // checked and thrown in WComponentPeer constructor. We can't throw an 525 // error here because this code is invoked on Toolkit thread 526 if (hwnd == NULL) 527 { 528 DWORD dw = ::GetLastError(); 529 jobject createError = NULL; 530 if (dw == ERROR_OUTOFMEMORY) 531 { 532 jstring errorMsg = JNU_NewStringPlatform(env, L"too many window handles"); 533 createError = JNU_NewObjectByName(env, "java/lang/OutOfMemoryError", 534 "(Ljava/lang/String;)V", 535 errorMsg); 536 env->DeleteLocalRef(errorMsg); 537 } 538 else 539 { 540 TCHAR *buf; 541 FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, 542 NULL, dw, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), 543 (LPTSTR)&buf, 0, NULL); 544 jstring s = JNU_NewStringPlatform(env, buf); 545 createError = JNU_NewObjectByName(env, "java/lang/InternalError", 546 "(Ljava/lang/String;)V", s); 547 LocalFree(buf); 548 env->DeleteLocalRef(s); 549 } 550 env->SetObjectField(peer, AwtObject::createErrorID, createError); 551 if (createError != NULL) 552 { 553 env->DeleteLocalRef(createError); 554 } 555 env->DeleteLocalRef(target); 556 return; 557 } 558 559 m_hwnd = hwnd; 560 561 ::ImmAssociateContext(m_hwnd, NULL); 562 563 SetDrawState((jint)JAWT_LOCK_SURFACE_CHANGED | 564 (jint)JAWT_LOCK_BOUNDS_CHANGED | 565 (jint)JAWT_LOCK_CLIP_CHANGED); 566 567 LinkObjects(env, peer); 568 569 /* Subclass the window now so that we can snoop on its messages */ 570 SubclassHWND(); 571 572 /* 573 * Fix for 4046446. 574 */ 575 SetWindowPos(GetHWnd(), 0, x, y, w, h, SWP_NOZORDER | SWP_NOCOPYBITS | SWP_NOACTIVATE); 576 577 /* Set default colors. */ 578 m_colorForeground = colorForeground; 579 m_colorBackground = colorBackground; 580 581 /* 582 * Only set background color if the color is actually set on the 583 * target -- this avoids inheriting a parent's color unnecessarily, 584 * and has to be done here because there isn't an API to get the 585 * real background color from outside the AWT package. 586 */ 587 jobject bkgrd = env->GetObjectField(target, AwtComponent::backgroundID) ; 588 if (bkgrd != NULL) { 589 JNU_CallMethodByName(env, NULL, peer, "setBackground", 590 "(Ljava/awt/Color;)V", bkgrd); 591 DASSERT(!safe_ExceptionOccurred(env)); 592 } 593 env->DeleteLocalRef(target); 594 env->DeleteLocalRef(bkgrd); 595 } 596 597 /* 598 * Destroy this window's HWND 599 */ 600 void AwtComponent::DestroyHWnd() { 601 if (m_hwnd != NULL) { 602 AwtToolkit::DestroyComponentHWND(m_hwnd); 603 //AwtToolkit::DestroyComponent(this); 604 m_hwnd = NULL; 605 } 606 } 607 608 /* 609 * Returns hwnd for target on non Toolkit thread 610 */ 611 HWND 612 AwtComponent::GetHWnd(JNIEnv* env, jobject target) { 613 if (JNU_IsNull(env, target)) { 614 return 0; 615 } 616 jobject peer = env->GetObjectField(target, AwtComponent::peerID); 617 if (JNU_IsNull(env, peer)) { 618 return 0; 619 } 620 HWND hwnd = reinterpret_cast<HWND>(static_cast<LONG_PTR> ( 621 env->GetLongField(peer, AwtComponent::hwndID))); 622 env->DeleteLocalRef(peer); 623 return hwnd; 624 } 625 // 626 // Propagate the background color to synchronize Java field and peer's field. 627 // This is needed to fix 4148334 628 // 629 void AwtComponent::UpdateBackground(JNIEnv *env, jobject target) 630 { 631 if (env->EnsureLocalCapacity(1) < 0) { 632 return; 633 } 634 635 jobject bkgrnd = env->GetObjectField(target, AwtComponent::backgroundID); 636 637 if (bkgrnd == NULL) { 638 bkgrnd = JNU_NewObjectByName(env, "java/awt/Color", "(III)V", 639 GetRValue(m_colorBackground), 640 GetGValue(m_colorBackground), 641 GetBValue(m_colorBackground)); 642 if (bkgrnd != NULL) { 643 env->SetObjectField(target, AwtComponent::backgroundID, bkgrnd); 644 } 645 } 646 env->DeleteLocalRef(bkgrnd); 647 } 648 649 /* 650 * Install our window proc as the proc for our HWND, and save off the 651 * previous proc as the default 652 */ 653 void AwtComponent::SubclassHWND() 654 { 655 if (m_bSubclassed) { 656 return; 657 } 658 const WNDPROC wndproc = WndProc; // let compiler type check WndProc 659 m_DefWindowProc = ComCtl32Util::GetInstance().SubclassHWND(GetHWnd(), wndproc); 660 m_bSubclassed = TRUE; 661 } 662 663 /* 664 * Reinstall the original window proc as the proc for our HWND 665 */ 666 void AwtComponent::UnsubclassHWND() 667 { 668 if (!m_bSubclassed) { 669 return; 670 } 671 ComCtl32Util::GetInstance().UnsubclassHWND(GetHWnd(), WndProc, m_DefWindowProc); 672 m_bSubclassed = FALSE; 673 } 674 675 ///////////////////////////////////// 676 // (static method) 677 // Determines the top-level ancestor for a given window. If the given 678 // window is a top-level window, return itself. 679 // 680 // 'Top-level' includes dialogs as well. 681 // 682 HWND AwtComponent::GetTopLevelParentForWindow(HWND hwndDescendant) { 683 if (hwndDescendant == NULL) { 684 return NULL; 685 } 686 687 DASSERT(IsWindow(hwndDescendant)); 688 HWND hwnd = hwndDescendant; 689 for(;;) { 690 DWORD style = ::GetWindowLong(hwnd, GWL_STYLE); 691 // a) found a non-child window so terminate 692 // b) found real toplevel window (e.g. EmbeddedFrame 693 // that is child though) 694 if ( (style & WS_CHILD) == 0 || 695 AwtComponent::IsTopLevelHWnd(hwnd) ) 696 { 697 break; 698 } 699 hwnd = ::GetParent(hwnd); 700 } 701 702 return hwnd; 703 } 704 //////////////////// 705 706 jobject AwtComponent::FindHeavyweightUnderCursor(BOOL useCache) { 707 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); 708 if (env->EnsureLocalCapacity(1) < 0) { 709 return NULL; 710 } 711 712 HWND hit = NULL; 713 POINT p = { 0, 0 }; 714 AwtComponent *comp = NULL; 715 716 if ((comp = AwtFrame::sm_lwFrameUnderMouse) != NULL) { 717 goto found; 718 } 719 720 if (useCache) { 721 if (sm_cursorOn == NULL) { 722 return NULL; 723 } 724 725 726 DASSERT(::IsWindow(sm_cursorOn)); 727 VERIFY(::GetCursorPos(&p)); 728 /* 729 * Fix for BugTraq ID 4304024. 730 * Allow a non-default cursor only for the client area. 731 */ 732 comp = AwtComponent::GetComponent(sm_cursorOn); 733 if (comp != NULL && 734 ::SendMessage(sm_cursorOn, WM_NCHITTEST, 0, 735 MAKELPARAM(p.x, p.y)) == HTCLIENT) { 736 goto found; 737 } 738 } 739 740 ::GetCursorPos(&p); 741 hit = ::WindowFromPoint(p); 742 while (hit != NULL) { 743 comp = AwtComponent::GetComponent(hit); 744 745 if (comp != NULL) { 746 INT nHittest = (INT)::SendMessage(hit, WM_NCHITTEST, 747 0, MAKELPARAM(p.x, p.y)); 748 /* 749 * Fix for BugTraq ID 4304024. 750 * Allow a non-default cursor only for the client area. 751 */ 752 if (nHittest != HTCLIENT) { 753 /* 754 * When over the non-client area, send WM_SETCURSOR 755 * to revert the cursor to an arrow. 756 */ 757 ::SendMessage(hit, WM_SETCURSOR, (WPARAM)hit, 758 MAKELPARAM(nHittest, WM_MOUSEMOVE)); 759 return NULL; 760 } else { 761 sm_cursorOn = hit; 762 goto found; 763 } 764 } 765 766 if ((::GetWindowLong(hit, GWL_STYLE) & WS_CHILD) == 0) { 767 return NULL; 768 } 769 hit = ::GetParent(hit); 770 } 771 772 return NULL; 773 774 found: 775 jobject localRef = comp->GetTarget(env); 776 jobject globalRef = env->NewGlobalRef(localRef); 777 env->DeleteLocalRef(localRef); 778 return globalRef; 779 } 780 781 void AwtComponent::SetColor(COLORREF c) 782 { 783 int screen = AwtWin32GraphicsDevice::DeviceIndexForWindow(GetHWnd()); 784 int grayscale = AwtWin32GraphicsDevice::GetGrayness(screen); 785 if (grayscale != GS_NOTGRAY) { 786 int g; 787 788 g = (int) (.299 * (c & 0xFF) + .587 * ((c >> 8) & 0xFF) + 789 .114 * ((c >> 16) & 0xFF) + 0.5); 790 // c = g | (g << 8) | (g << 16); 791 c = PALETTERGB(g, g, g); 792 } 793 794 if (m_colorForeground == c) { 795 return; 796 } 797 798 m_colorForeground = c; 799 if (m_penForeground != NULL) { 800 m_penForeground->Release(); 801 m_penForeground = NULL; 802 } 803 VERIFY(::InvalidateRect(GetHWnd(), NULL, FALSE)); 804 } 805 806 void AwtComponent::SetBackgroundColor(COLORREF c) 807 { 808 int screen = AwtWin32GraphicsDevice::DeviceIndexForWindow(GetHWnd()); 809 int grayscale = AwtWin32GraphicsDevice::GetGrayness(screen); 810 if (grayscale != GS_NOTGRAY) { 811 int g; 812 813 g = (int) (.299 * (c & 0xFF) + .587 * ((c >> 8) & 0xFF) + 814 .114 * ((c >> 16) & 0xFF) + 0.5); 815 // c = g | (g << 8) | (g << 16); 816 c = PALETTERGB(g, g, g); 817 } 818 819 if (m_colorBackground == c) { 820 return; 821 } 822 m_colorBackground = c; 823 m_backgroundColorSet = TRUE; 824 if (m_brushBackground != NULL) { 825 m_brushBackground->Release(); 826 m_brushBackground = NULL; 827 } 828 VERIFY(::InvalidateRect(GetHWnd(), NULL, TRUE)); 829 } 830 831 HPEN AwtComponent::GetForegroundPen() 832 { 833 if (m_penForeground == NULL) { 834 m_penForeground = AwtPen::Get(m_colorForeground); 835 } 836 return (HPEN)m_penForeground->GetHandle(); 837 } 838 839 COLORREF AwtComponent::GetBackgroundColor() 840 { 841 if (m_backgroundColorSet == FALSE) { 842 AwtComponent* c = this; 843 while ((c = c->GetParent()) != NULL) { 844 if (c->IsBackgroundColorSet()) { 845 return c->GetBackgroundColor(); 846 } 847 } 848 } 849 return m_colorBackground; 850 } 851 852 HBRUSH AwtComponent::GetBackgroundBrush() 853 { 854 if (m_backgroundColorSet == FALSE) { 855 if (m_brushBackground != NULL) { 856 m_brushBackground->Release(); 857 m_brushBackground = NULL; 858 } 859 AwtComponent* c = this; 860 while ((c = c->GetParent()) != NULL) { 861 if (c->IsBackgroundColorSet()) { 862 m_brushBackground = 863 AwtBrush::Get(c->GetBackgroundColor()); 864 break; 865 } 866 } 867 } 868 if (m_brushBackground == NULL) { 869 m_brushBackground = AwtBrush::Get(m_colorBackground); 870 } 871 return (HBRUSH)m_brushBackground->GetHandle(); 872 } 873 874 void AwtComponent::SetFont(AwtFont* font) 875 { 876 DASSERT(font != NULL); 877 if (font->GetAscent() < 0) { 878 AwtFont::SetupAscent(font); 879 } 880 SendMessage(WM_SETFONT, (WPARAM)font->GetHFont(), MAKELPARAM(FALSE, 0)); 881 VERIFY(::InvalidateRect(GetHWnd(), NULL, TRUE)); 882 } 883 884 AwtComponent* AwtComponent::GetParent() 885 { 886 HWND hwnd = ::GetParent(GetHWnd()); 887 if (hwnd == NULL) { 888 return NULL; 889 } 890 return GetComponent(hwnd); 891 } 892 893 AwtWindow* AwtComponent::GetContainer() 894 { 895 AwtComponent* comp = this; 896 while (comp != NULL) { 897 if (comp->IsContainer()) { 898 return (AwtWindow*)comp; 899 } 900 comp = comp->GetParent(); 901 } 902 return NULL; 903 } 904 905 void AwtComponent::Show() 906 { 907 m_visible = true; 908 ::ShowWindow(GetHWnd(), SW_SHOWNA); 909 } 910 911 void AwtComponent::Hide() 912 { 913 m_visible = false; 914 ::ShowWindow(GetHWnd(), SW_HIDE); 915 } 916 917 BOOL 918 AwtComponent::SetWindowPos(HWND wnd, HWND after, 919 int x, int y, int w, int h, UINT flags) 920 { 921 // Conditions we shouldn't handle: 922 // z-order changes, correct window dimensions 923 if (after != NULL || (w < 32767 && h < 32767) 924 || ((::GetWindowLong(wnd, GWL_STYLE) & WS_CHILD) == 0)) 925 { 926 return ::SetWindowPos(wnd, after, x, y, w, h, flags); 927 } 928 WINDOWPLACEMENT wp; 929 ::ZeroMemory(&wp, sizeof(wp)); 930 931 wp.length = sizeof(wp); 932 ::GetWindowPlacement(wnd, &wp); 933 wp.rcNormalPosition.left = x; 934 wp.rcNormalPosition.top = y; 935 wp.rcNormalPosition.right = x + w; 936 wp.rcNormalPosition.bottom = y + h; 937 if ( flags & SWP_NOACTIVATE ) { 938 wp.showCmd = SW_SHOWNOACTIVATE; 939 } 940 ::SetWindowPlacement(wnd, &wp); 941 return 1; 942 } 943 944 945 void AwtComponent::Reshape(int x, int y, int w, int h) 946 { 947 #if defined(DEBUG) 948 RECT rc; 949 ::GetWindowRect(GetHWnd(), &rc); 950 ::MapWindowPoints(HWND_DESKTOP, ::GetParent(GetHWnd()), (LPPOINT)&rc, 2); 951 DTRACE_PRINTLN4("AwtComponent::Reshape from %d, %d, %d, %d", rc.left, rc.top, rc.right-rc.left, rc.bottom-rc.top); 952 #endif 953 AwtWindow* container = GetContainer(); 954 AwtComponent* parent = GetParent(); 955 if (container != NULL && container == parent) { 956 container->SubtractInsetPoint(x, y); 957 } 958 DTRACE_PRINTLN4("AwtComponent::Reshape to %d, %d, %d, %d", x, y, w, h); 959 UINT flags = SWP_NOACTIVATE | SWP_NOZORDER; 960 961 RECT r; 962 963 ::GetWindowRect(GetHWnd(), &r); 964 // if the component size is changing , don't copy window bits 965 if (r.right - r.left != w || r.bottom - r.top != h) { 966 flags |= SWP_NOCOPYBITS; 967 } 968 969 if (parent && _tcscmp(parent->GetClassName(), TEXT("SunAwtScrollPane")) == 0) { 970 if (x > 0) { 971 x = 0; 972 } 973 if (y > 0) { 974 y = 0; 975 } 976 } 977 if (m_hdwp != NULL) { 978 m_hdwp = ::DeferWindowPos(m_hdwp, GetHWnd(), 0, x, y, w, h, flags); 979 DASSERT(m_hdwp != NULL); 980 } else { 981 /* 982 * Fox for 4046446 983 * If window has dimensions above the short int limit, ::SetWindowPos doesn't work. 984 * We should use SetWindowPlacement instead. 985 */ 986 SetWindowPos(GetHWnd(), 0, x, y, w, h, flags); 987 } 988 } 989 990 void AwtComponent::SetScrollValues(UINT bar, int min, int value, int max) 991 { 992 int minTmp, maxTmp; 993 994 ::GetScrollRange(GetHWnd(), bar, &minTmp, &maxTmp); 995 if (min == INT_MAX) { 996 min = minTmp; 997 } 998 if (value == INT_MAX) { 999 value = ::GetScrollPos(GetHWnd(), bar); 1000 } 1001 if (max == INT_MAX) { 1002 max = maxTmp; 1003 } 1004 if (min == max) { 1005 max++; 1006 } 1007 ::SetScrollRange(GetHWnd(), bar, min, max, FALSE); 1008 ::SetScrollPos(GetHWnd(), bar, value, TRUE); 1009 } 1010 1011 /* 1012 * Save Global Reference of sun.awt.windows.WInputMethod object 1013 */ 1014 void AwtComponent::SetInputMethod(jobject im, BOOL useNativeCompWindow) 1015 { 1016 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); 1017 1018 if (m_InputMethod!=NULL) 1019 env->DeleteGlobalRef(m_InputMethod); 1020 1021 if (im!=NULL){ 1022 m_InputMethod = env->NewGlobalRef(im); 1023 m_useNativeCompWindow = useNativeCompWindow; 1024 } else { 1025 m_InputMethod = NULL; 1026 m_useNativeCompWindow = TRUE; 1027 } 1028 1029 } 1030 1031 /* 1032 * Opportunity to process and/or eat a message before it is dispatched 1033 */ 1034 MsgRouting AwtComponent::PreProcessMsg(MSG& msg) 1035 { 1036 return mrPassAlong; 1037 } 1038 1039 static UINT lastMessage = WM_NULL; 1040 1041 #ifndef SPY_MESSAGES 1042 #define SpyWinMessage(hwin,msg,str) 1043 #else 1044 1045 #define FMT_MSG(x,y) case x: _stprintf(szBuf, \ 1046 "0x%8.8x(%s):%s\n", hwnd, szComment, y); break; 1047 #define WIN_MSG(x) FMT_MSG(x,#x) 1048 1049 void SpyWinMessage(HWND hwnd, UINT message, LPCTSTR szComment) { 1050 1051 TCHAR szBuf[256]; 1052 1053 switch (message) { 1054 WIN_MSG(WM_NULL) 1055 WIN_MSG(WM_CREATE) 1056 WIN_MSG(WM_DESTROY) 1057 WIN_MSG(WM_MOVE) 1058 WIN_MSG(WM_SIZE) 1059 WIN_MSG(WM_ACTIVATE) 1060 WIN_MSG(WM_SETFOCUS) 1061 WIN_MSG(WM_KILLFOCUS) 1062 WIN_MSG(WM_ENABLE) 1063 WIN_MSG(WM_SETREDRAW) 1064 WIN_MSG(WM_SETTEXT) 1065 WIN_MSG(WM_GETTEXT) 1066 WIN_MSG(WM_GETTEXTLENGTH) 1067 WIN_MSG(WM_PAINT) 1068 WIN_MSG(WM_CLOSE) 1069 WIN_MSG(WM_QUERYENDSESSION) 1070 WIN_MSG(WM_QUIT) 1071 WIN_MSG(WM_QUERYOPEN) 1072 WIN_MSG(WM_ERASEBKGND) 1073 WIN_MSG(WM_SYSCOLORCHANGE) 1074 WIN_MSG(WM_ENDSESSION) 1075 WIN_MSG(WM_SHOWWINDOW) 1076 FMT_MSG(WM_WININICHANGE,"WM_WININICHANGE/WM_SETTINGCHANGE") 1077 WIN_MSG(WM_DEVMODECHANGE) 1078 WIN_MSG(WM_ACTIVATEAPP) 1079 WIN_MSG(WM_FONTCHANGE) 1080 WIN_MSG(WM_TIMECHANGE) 1081 WIN_MSG(WM_CANCELMODE) 1082 WIN_MSG(WM_SETCURSOR) 1083 WIN_MSG(WM_MOUSEACTIVATE) 1084 WIN_MSG(WM_CHILDACTIVATE) 1085 WIN_MSG(WM_QUEUESYNC) 1086 WIN_MSG(WM_GETMINMAXINFO) 1087 WIN_MSG(WM_PAINTICON) 1088 WIN_MSG(WM_ICONERASEBKGND) 1089 WIN_MSG(WM_NEXTDLGCTL) 1090 WIN_MSG(WM_SPOOLERSTATUS) 1091 WIN_MSG(WM_DRAWITEM) 1092 WIN_MSG(WM_MEASUREITEM) 1093 WIN_MSG(WM_DELETEITEM) 1094 WIN_MSG(WM_VKEYTOITEM) 1095 WIN_MSG(WM_CHARTOITEM) 1096 WIN_MSG(WM_SETFONT) 1097 WIN_MSG(WM_GETFONT) 1098 WIN_MSG(WM_SETHOTKEY) 1099 WIN_MSG(WM_GETHOTKEY) 1100 WIN_MSG(WM_QUERYDRAGICON) 1101 WIN_MSG(WM_COMPAREITEM) 1102 FMT_MSG(0x003D, "WM_GETOBJECT") 1103 WIN_MSG(WM_COMPACTING) 1104 WIN_MSG(WM_COMMNOTIFY) 1105 WIN_MSG(WM_WINDOWPOSCHANGING) 1106 WIN_MSG(WM_WINDOWPOSCHANGED) 1107 WIN_MSG(WM_POWER) 1108 WIN_MSG(WM_COPYDATA) 1109 WIN_MSG(WM_CANCELJOURNAL) 1110 WIN_MSG(WM_NOTIFY) 1111 WIN_MSG(WM_INPUTLANGCHANGEREQUEST) 1112 WIN_MSG(WM_INPUTLANGCHANGE) 1113 WIN_MSG(WM_TCARD) 1114 WIN_MSG(WM_HELP) 1115 WIN_MSG(WM_USERCHANGED) 1116 WIN_MSG(WM_NOTIFYFORMAT) 1117 WIN_MSG(WM_CONTEXTMENU) 1118 WIN_MSG(WM_STYLECHANGING) 1119 WIN_MSG(WM_STYLECHANGED) 1120 WIN_MSG(WM_DISPLAYCHANGE) 1121 WIN_MSG(WM_GETICON) 1122 WIN_MSG(WM_SETICON) 1123 WIN_MSG(WM_NCCREATE) 1124 WIN_MSG(WM_NCDESTROY) 1125 WIN_MSG(WM_NCCALCSIZE) 1126 WIN_MSG(WM_NCHITTEST) 1127 WIN_MSG(WM_NCPAINT) 1128 WIN_MSG(WM_NCACTIVATE) 1129 WIN_MSG(WM_GETDLGCODE) 1130 WIN_MSG(WM_SYNCPAINT) 1131 WIN_MSG(WM_NCMOUSEMOVE) 1132 WIN_MSG(WM_NCLBUTTONDOWN) 1133 WIN_MSG(WM_NCLBUTTONUP) 1134 WIN_MSG(WM_NCLBUTTONDBLCLK) 1135 WIN_MSG(WM_NCRBUTTONDOWN) 1136 WIN_MSG(WM_NCRBUTTONUP) 1137 WIN_MSG(WM_NCRBUTTONDBLCLK) 1138 WIN_MSG(WM_NCMBUTTONDOWN) 1139 WIN_MSG(WM_NCMBUTTONUP) 1140 WIN_MSG(WM_NCMBUTTONDBLCLK) 1141 WIN_MSG(WM_KEYDOWN) 1142 WIN_MSG(WM_KEYUP) 1143 WIN_MSG(WM_CHAR) 1144 WIN_MSG(WM_DEADCHAR) 1145 WIN_MSG(WM_SYSKEYDOWN) 1146 WIN_MSG(WM_SYSKEYUP) 1147 WIN_MSG(WM_SYSCHAR) 1148 WIN_MSG(WM_SYSDEADCHAR) 1149 WIN_MSG(WM_IME_STARTCOMPOSITION) 1150 WIN_MSG(WM_IME_ENDCOMPOSITION) 1151 WIN_MSG(WM_IME_COMPOSITION) 1152 WIN_MSG(WM_INITDIALOG) 1153 WIN_MSG(WM_COMMAND) 1154 WIN_MSG(WM_SYSCOMMAND) 1155 WIN_MSG(WM_TIMER) 1156 WIN_MSG(WM_HSCROLL) 1157 WIN_MSG(WM_VSCROLL) 1158 WIN_MSG(WM_INITMENU) 1159 WIN_MSG(WM_INITMENUPOPUP) 1160 WIN_MSG(WM_MENUSELECT) 1161 WIN_MSG(WM_MENUCHAR) 1162 WIN_MSG(WM_ENTERIDLE) 1163 FMT_MSG(0x0122, "WM_MENURBUTTONUP") 1164 FMT_MSG(0x0123, "WM_MENUDRAG") 1165 FMT_MSG(0x0124, "WM_MENUGETOBJECT") 1166 FMT_MSG(0x0125, "WM_UNINITMENUPOPUP") 1167 FMT_MSG(0x0126, "WM_MENUCOMMAND") 1168 WIN_MSG(WM_CTLCOLORMSGBOX) 1169 WIN_MSG(WM_CTLCOLOREDIT) 1170 WIN_MSG(WM_CTLCOLORLISTBOX) 1171 WIN_MSG(WM_CTLCOLORBTN) 1172 WIN_MSG(WM_CTLCOLORDLG) 1173 WIN_MSG(WM_CTLCOLORSCROLLBAR) 1174 WIN_MSG(WM_CTLCOLORSTATIC) 1175 WIN_MSG(WM_MOUSEMOVE) 1176 WIN_MSG(WM_LBUTTONDOWN) 1177 WIN_MSG(WM_LBUTTONUP) 1178 WIN_MSG(WM_LBUTTONDBLCLK) 1179 WIN_MSG(WM_RBUTTONDOWN) 1180 WIN_MSG(WM_RBUTTONUP) 1181 WIN_MSG(WM_RBUTTONDBLCLK) 1182 WIN_MSG(WM_MBUTTONDOWN) 1183 WIN_MSG(WM_MBUTTONUP) 1184 WIN_MSG(WM_MBUTTONDBLCLK) 1185 WIN_MSG(WM_XBUTTONDBLCLK) 1186 WIN_MSG(WM_XBUTTONDOWN) 1187 WIN_MSG(WM_XBUTTONUP) 1188 WIN_MSG(WM_MOUSEWHEEL) 1189 WIN_MSG(WM_PARENTNOTIFY) 1190 WIN_MSG(WM_ENTERMENULOOP) 1191 WIN_MSG(WM_EXITMENULOOP) 1192 WIN_MSG(WM_NEXTMENU) 1193 WIN_MSG(WM_SIZING) 1194 WIN_MSG(WM_CAPTURECHANGED) 1195 WIN_MSG(WM_MOVING) 1196 WIN_MSG(WM_POWERBROADCAST) 1197 WIN_MSG(WM_DEVICECHANGE) 1198 WIN_MSG(WM_MDICREATE) 1199 WIN_MSG(WM_MDIDESTROY) 1200 WIN_MSG(WM_MDIACTIVATE) 1201 WIN_MSG(WM_MDIRESTORE) 1202 WIN_MSG(WM_MDINEXT) 1203 WIN_MSG(WM_MDIMAXIMIZE) 1204 WIN_MSG(WM_MDITILE) 1205 WIN_MSG(WM_MDICASCADE) 1206 WIN_MSG(WM_MDIICONARRANGE) 1207 WIN_MSG(WM_MDIGETACTIVE) 1208 WIN_MSG(WM_MDISETMENU) 1209 WIN_MSG(WM_ENTERSIZEMOVE) 1210 WIN_MSG(WM_EXITSIZEMOVE) 1211 WIN_MSG(WM_DROPFILES) 1212 WIN_MSG(WM_MDIREFRESHMENU) 1213 WIN_MSG(WM_IME_SETCONTEXT) 1214 WIN_MSG(WM_IME_NOTIFY) 1215 WIN_MSG(WM_IME_CONTROL) 1216 WIN_MSG(WM_IME_COMPOSITIONFULL) 1217 WIN_MSG(WM_IME_SELECT) 1218 WIN_MSG(WM_IME_CHAR) 1219 FMT_MSG(WM_IME_REQUEST) 1220 WIN_MSG(WM_IME_KEYDOWN) 1221 WIN_MSG(WM_IME_KEYUP) 1222 FMT_MSG(0x02A1, "WM_MOUSEHOVER") 1223 FMT_MSG(0x02A3, "WM_MOUSELEAVE") 1224 WIN_MSG(WM_CUT) 1225 WIN_MSG(WM_COPY) 1226 WIN_MSG(WM_PASTE) 1227 WIN_MSG(WM_CLEAR) 1228 WIN_MSG(WM_UNDO) 1229 WIN_MSG(WM_RENDERFORMAT) 1230 WIN_MSG(WM_RENDERALLFORMATS) 1231 WIN_MSG(WM_DESTROYCLIPBOARD) 1232 WIN_MSG(WM_DRAWCLIPBOARD) 1233 WIN_MSG(WM_PAINTCLIPBOARD) 1234 WIN_MSG(WM_VSCROLLCLIPBOARD) 1235 WIN_MSG(WM_SIZECLIPBOARD) 1236 WIN_MSG(WM_ASKCBFORMATNAME) 1237 WIN_MSG(WM_CHANGECBCHAIN) 1238 WIN_MSG(WM_HSCROLLCLIPBOARD) 1239 WIN_MSG(WM_QUERYNEWPALETTE) 1240 WIN_MSG(WM_PALETTEISCHANGING) 1241 WIN_MSG(WM_PALETTECHANGED) 1242 WIN_MSG(WM_HOTKEY) 1243 WIN_MSG(WM_PRINT) 1244 WIN_MSG(WM_PRINTCLIENT) 1245 WIN_MSG(WM_HANDHELDFIRST) 1246 WIN_MSG(WM_HANDHELDLAST) 1247 WIN_MSG(WM_AFXFIRST) 1248 WIN_MSG(WM_AFXLAST) 1249 WIN_MSG(WM_PENWINFIRST) 1250 WIN_MSG(WM_PENWINLAST) 1251 WIN_MSG(WM_AWT_COMPONENT_CREATE) 1252 WIN_MSG(WM_AWT_DESTROY_WINDOW) 1253 WIN_MSG(WM_AWT_MOUSEENTER) 1254 WIN_MSG(WM_AWT_MOUSEEXIT) 1255 WIN_MSG(WM_AWT_COMPONENT_SHOW) 1256 WIN_MSG(WM_AWT_COMPONENT_HIDE) 1257 WIN_MSG(WM_AWT_COMPONENT_SETFOCUS) 1258 WIN_MSG(WM_AWT_WINDOW_SETACTIVE) 1259 WIN_MSG(WM_AWT_LIST_SETMULTISELECT) 1260 WIN_MSG(WM_AWT_HANDLE_EVENT) 1261 WIN_MSG(WM_AWT_PRINT_COMPONENT) 1262 WIN_MSG(WM_AWT_RESHAPE_COMPONENT) 1263 WIN_MSG(WM_AWT_SETALWAYSONTOP) 1264 WIN_MSG(WM_AWT_BEGIN_VALIDATE) 1265 WIN_MSG(WM_AWT_END_VALIDATE) 1266 WIN_MSG(WM_AWT_FORWARD_CHAR) 1267 WIN_MSG(WM_AWT_FORWARD_BYTE) 1268 WIN_MSG(WM_AWT_SET_SCROLL_INFO) 1269 WIN_MSG(WM_AWT_CREATECONTEXT) 1270 WIN_MSG(WM_AWT_DESTROYCONTEXT) 1271 WIN_MSG(WM_AWT_ASSOCIATECONTEXT) 1272 WIN_MSG(WM_AWT_GET_DEFAULT_IME_HANDLER) 1273 WIN_MSG(WM_AWT_HANDLE_NATIVE_IME_EVENT) 1274 WIN_MSG(WM_AWT_PRE_KEYDOWN) 1275 WIN_MSG(WM_AWT_PRE_KEYUP) 1276 WIN_MSG(WM_AWT_PRE_SYSKEYDOWN) 1277 WIN_MSG(WM_AWT_PRE_SYSKEYUP) 1278 WIN_MSG(WM_AWT_ENDCOMPOSITION,) 1279 WIN_MSG(WM_AWT_DISPOSE,) 1280 WIN_MSG(WM_AWT_DELETEOBJECT,) 1281 WIN_MSG(WM_AWT_SETCONVERSIONSTATUS,) 1282 WIN_MSG(WM_AWT_GETCONVERSIONSTATUS,) 1283 WIN_MSG(WM_AWT_SETOPENSTATUS,) 1284 WIN_MSG(WM_AWT_GETOPENSTATUS) 1285 WIN_MSG(WM_AWT_ACTIVATEKEYBOARDLAYOUT) 1286 WIN_MSG(WM_AWT_OPENCANDIDATEWINDOW) 1287 WIN_MSG(WM_AWT_DLG_SHOWMODAL,) 1288 WIN_MSG(WM_AWT_DLG_ENDMODAL,) 1289 WIN_MSG(WM_AWT_SETCURSOR,) 1290 WIN_MSG(WM_AWT_WAIT_FOR_SINGLE_OBJECT,) 1291 WIN_MSG(WM_AWT_INVOKE_METHOD,) 1292 WIN_MSG(WM_AWT_INVOKE_VOID_METHOD,) 1293 WIN_MSG(WM_AWT_EXECUTE_SYNC,) 1294 WIN_MSG(WM_AWT_CURSOR_SYNC) 1295 WIN_MSG(WM_AWT_GETDC) 1296 WIN_MSG(WM_AWT_RELEASEDC) 1297 WIN_MSG(WM_AWT_RELEASE_ALL_DCS) 1298 WIN_MSG(WM_AWT_SHOWCURSOR) 1299 WIN_MSG(WM_AWT_HIDECURSOR) 1300 WIN_MSG(WM_AWT_CREATE_PRINTED_PIXELS) 1301 WIN_MSG(WM_AWT_OBJECTLISTCLEANUP) 1302 default: 1303 sprintf(szBuf, "0x%8.8x(%s):Unknown message 0x%8.8x\n", 1304 hwnd, szComment, message); 1305 break; 1306 } 1307 printf(szBuf); 1308 } 1309 1310 #endif /* SPY_MESSAGES */ 1311 1312 /* 1313 * Dispatch messages for this window class--general component 1314 */ 1315 LRESULT AwtComponent::WindowProc(UINT message, WPARAM wParam, LPARAM lParam) 1316 { 1317 CounterHelper ch(&m_MessagesProcessing); 1318 1319 JNILocalFrame lframe(AwtToolkit::GetEnv(), 10); 1320 SpyWinMessage(GetHWnd(), message, 1321 (message == WM_AWT_RELEASE_ALL_DCS) ? TEXT("Disposed Component") : GetClassName()); 1322 1323 LRESULT retValue = 0; 1324 MsgRouting mr = mrDoDefault; 1325 AwtToolkit::GetInstance().eventNumber++; 1326 1327 static BOOL ignoreNextLBTNUP = FALSE; //Ignore next LBUTTONUP msg? 1328 1329 lastMessage = message; 1330 1331 if (message == WmAwtIsComponent) { 1332 // special message to identify AWT HWND's without using 1333 // resource hogging ::SetProp 1334 return (LRESULT)TRUE; 1335 } 1336 1337 DWORD curPos = 0; 1338 1339 UINT switchMessage = message; 1340 switch (switchMessage) { 1341 case WM_AWT_GETDC: 1342 { 1343 HDC hDC; 1344 // First, release the DCs scheduled for deletion 1345 ReleaseDCList(GetHWnd(), passiveDCList); 1346 1347 GetDCReturnStruct *returnStruct = new GetDCReturnStruct; 1348 returnStruct->gdiLimitReached = FALSE; 1349 if (AwtGDIObject::IncrementIfAvailable()) { 1350 hDC = ::GetDCEx(GetHWnd(), NULL, 1351 DCX_CACHE | DCX_CLIPCHILDREN | 1352 DCX_CLIPSIBLINGS); 1353 if (hDC != NULL) { 1354 // Add new DC to list of DC's associated with this Component 1355 activeDCList.AddDC(hDC, GetHWnd()); 1356 } else { 1357 // Creation failed; decrement counter in AwtGDIObject 1358 AwtGDIObject::Decrement(); 1359 } 1360 } else { 1361 hDC = NULL; 1362 returnStruct->gdiLimitReached = TRUE; 1363 } 1364 returnStruct->hDC = hDC; 1365 retValue = (LRESULT)returnStruct; 1366 mr = mrConsume; 1367 break; 1368 } 1369 case WM_AWT_RELEASEDC: 1370 { 1371 HDC hDC = (HDC)wParam; 1372 MoveDCToPassiveList(hDC); 1373 ReleaseDCList(GetHWnd(), passiveDCList); 1374 mr = mrConsume; 1375 break; 1376 } 1377 case WM_AWT_RELEASE_ALL_DCS: 1378 { 1379 // Called during Component destruction. Gets current list of 1380 // DC's associated with Component and releases each DC. 1381 ReleaseDCList(GetHWnd(), activeDCList); 1382 ReleaseDCList(GetHWnd(), passiveDCList); 1383 mr = mrConsume; 1384 break; 1385 } 1386 case WM_AWT_SHOWCURSOR: 1387 ::ShowCursor(TRUE); 1388 break; 1389 case WM_AWT_HIDECURSOR: 1390 ::ShowCursor(FALSE); 1391 break; 1392 case WM_CREATE: mr = WmCreate(); break; 1393 case WM_CLOSE: mr = WmClose(); break; 1394 case WM_DESTROY: mr = WmDestroy(); break; 1395 case WM_NCDESTROY: mr = WmNcDestroy(); break; 1396 1397 case WM_ERASEBKGND: 1398 mr = WmEraseBkgnd((HDC)wParam, *(BOOL*)&retValue); break; 1399 case WM_PAINT: 1400 CheckFontSmoothingSettings(GetHWnd()); 1401 /* Set draw state */ 1402 SetDrawState(GetDrawState() | JAWT_LOCK_CLIP_CHANGED); 1403 mr = WmPaint((HDC)wParam); 1404 break; 1405 1406 case WM_GETMINMAXINFO: 1407 mr = WmGetMinMaxInfo((LPMINMAXINFO)lParam); 1408 break; 1409 1410 case WM_WINDOWPOSCHANGING: 1411 { 1412 // We process this message so that we can synchronize access to 1413 // a moving window. The Scale/Blt functions in Win32BlitLoops 1414 // take the same windowMoveLock to ensure that a window is not 1415 // moving while we are trying to copy pixels into it. 1416 WINDOWPOS *lpPosInfo = (WINDOWPOS *)lParam; 1417 if ((lpPosInfo->flags & (SWP_NOMOVE | SWP_NOSIZE)) != 1418 (SWP_NOMOVE | SWP_NOSIZE)) 1419 { 1420 // Move or Size command. 1421 // Windows tends to send erroneous events that the window 1422 // is about to move when the coordinates are exactly the 1423 // same as the last time. This can cause problems with 1424 // our windowMoveLock CriticalSection because we enter it 1425 // here and never get to WM_WINDOWPOSCHANGED to release it. 1426 // So make sure this is a real move/size event before bothering 1427 // to grab the critical section. 1428 BOOL takeLock = FALSE; 1429 if (!(lpPosInfo->flags & SWP_NOMOVE) && 1430 ((windowMoveLockPosX != lpPosInfo->x) || 1431 (windowMoveLockPosY != lpPosInfo->y))) 1432 { 1433 // Real move event 1434 takeLock = TRUE; 1435 windowMoveLockPosX = lpPosInfo->x; 1436 windowMoveLockPosY = lpPosInfo->y; 1437 } 1438 if (!(lpPosInfo->flags & SWP_NOSIZE) && 1439 ((windowMoveLockPosCX != lpPosInfo->cx) || 1440 (windowMoveLockPosCY != lpPosInfo->cy))) 1441 { 1442 // Real size event 1443 takeLock = TRUE; 1444 windowMoveLockPosCX = lpPosInfo->cx; 1445 windowMoveLockPosCY = lpPosInfo->cy; 1446 } 1447 if (takeLock) { 1448 if (!windowMoveLockHeld) { 1449 windowMoveLock.Enter(); 1450 windowMoveLockHeld = TRUE; 1451 } 1452 } 1453 } 1454 mr = WmWindowPosChanging(lParam); 1455 break; 1456 } 1457 case WM_WINDOWPOSCHANGED: 1458 { 1459 // Release lock grabbed in the POSCHANGING message 1460 if (windowMoveLockHeld) { 1461 windowMoveLockHeld = FALSE; 1462 windowMoveLock.Leave(); 1463 } 1464 mr = WmWindowPosChanged(lParam); 1465 break; 1466 } 1467 case WM_MOVE: { 1468 RECT r; 1469 ::GetWindowRect(GetHWnd(), &r); 1470 mr = WmMove(r.left, r.top); 1471 break; 1472 } 1473 case WM_SIZE: 1474 { 1475 RECT r; 1476 // fix 4128317 : use GetClientRect for full 32-bit int precision and 1477 // to avoid negative client area dimensions overflowing 16-bit params - robi 1478 ::GetClientRect( GetHWnd(), &r ); 1479 mr = WmSize(static_cast<UINT>(wParam), r.right - r.left, r.bottom - r.top); 1480 //mr = WmSize(wParam, LOWORD(lParam), HIWORD(lParam)); 1481 SetCompositionWindow(r); 1482 break; 1483 } 1484 case WM_SIZING: 1485 mr = WmSizing(); 1486 break; 1487 case WM_SHOWWINDOW: 1488 mr = WmShowWindow(static_cast<BOOL>(wParam), 1489 static_cast<UINT>(lParam)); break; 1490 case WM_SYSCOMMAND: 1491 mr = WmSysCommand(static_cast<UINT>(wParam & 0xFFF0), 1492 GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam)); 1493 break; 1494 case WM_EXITSIZEMOVE: 1495 mr = WmExitSizeMove(); 1496 break; 1497 // Bug #4039858 (Selecting menu item causes bogus mouse click event) 1498 case WM_ENTERMENULOOP: 1499 mr = WmEnterMenuLoop((BOOL)wParam); 1500 sm_bMenuLoop = TRUE; 1501 // we need to release grab if menu is shown 1502 if (AwtWindow::GetGrabbedWindow() != NULL) { 1503 AwtWindow::GetGrabbedWindow()->Ungrab(); 1504 } 1505 break; 1506 case WM_EXITMENULOOP: 1507 mr = WmExitMenuLoop((BOOL)wParam); 1508 sm_bMenuLoop = FALSE; 1509 break; 1510 1511 // We don't expect any focus messages on non-proxy component, 1512 // except those that came from Java. 1513 case WM_SETFOCUS: 1514 if (sm_inSynthesizeFocus) { 1515 mr = WmSetFocus((HWND)wParam); 1516 } else { 1517 mr = mrConsume; 1518 } 1519 break; 1520 case WM_KILLFOCUS: 1521 if (sm_inSynthesizeFocus) { 1522 mr = WmKillFocus((HWND)wParam); 1523 } else { 1524 mr = mrConsume; 1525 } 1526 break; 1527 case WM_ACTIVATE: { 1528 UINT nState = LOWORD(wParam); 1529 BOOL fMinimized = (BOOL)HIWORD(wParam); 1530 mr = mrConsume; 1531 1532 if (!sm_suppressFocusAndActivation && 1533 (!fMinimized || (nState == WA_INACTIVE))) 1534 { 1535 mr = WmActivate(nState, fMinimized, (HWND)lParam); 1536 1537 // When the window is deactivated, send WM_IME_ENDCOMPOSITION 1538 // message to deactivate the composition window so that 1539 // it won't receive keyboard input focus. 1540 HIMC hIMC; 1541 HWND hwnd = ImmGetHWnd(); 1542 if ((hIMC = ImmGetContext(hwnd)) != NULL) { 1543 ImmReleaseContext(hwnd, hIMC); 1544 DefWindowProc(WM_IME_ENDCOMPOSITION, 0, 0); 1545 } 1546 } 1547 break; 1548 } 1549 case WM_MOUSEACTIVATE: { 1550 AwtWindow *window = GetContainer(); 1551 if (window && window->IsFocusableWindow()) { 1552 // AWT/Swing will later request focus to a proper component 1553 // on handling the Java mouse event. Anyway, we have to 1554 // activate the window here as it works both for AWT & Swing. 1555 // Do it in our own fassion, 1556 window->AwtSetActiveWindow(TRUE, LOWORD(lParam)/*hittest*/); 1557 } 1558 mr = mrConsume; 1559 retValue = MA_NOACTIVATE; 1560 break; 1561 } 1562 case WM_CTLCOLORMSGBOX: 1563 case WM_CTLCOLOREDIT: 1564 case WM_CTLCOLORLISTBOX: 1565 case WM_CTLCOLORBTN: 1566 case WM_CTLCOLORDLG: 1567 case WM_CTLCOLORSCROLLBAR: 1568 case WM_CTLCOLORSTATIC: 1569 mr = WmCtlColor((HDC)wParam, (HWND)lParam, 1570 message-WM_CTLCOLORMSGBOX+CTLCOLOR_MSGBOX, 1571 *(HBRUSH*)&retValue); 1572 break; 1573 case WM_HSCROLL: 1574 mr = WmHScroll(LOWORD(wParam), HIWORD(wParam), (HWND)lParam); 1575 break; 1576 case WM_VSCROLL: 1577 mr = WmVScroll(LOWORD(wParam), HIWORD(wParam), (HWND)lParam); 1578 break; 1579 // 4664415: We're seeing a WM_LBUTTONUP when the user releases the 1580 // mouse button after a WM_NCLBUTTONDBLCLK. We want to ignore this 1581 // WM_LBUTTONUP, so we set a flag in WM_NCLBUTTONDBLCLK and look for the 1582 // flag on a WM_LBUTTONUP. -bchristi 1583 case WM_NCLBUTTONDBLCLK: 1584 mr = WmNcMouseDown(wParam, GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam), LEFT_BUTTON | DBL_CLICK); 1585 if (mr == mrDoDefault) { 1586 ignoreNextLBTNUP = TRUE; 1587 } 1588 break; 1589 case WM_NCLBUTTONDOWN: 1590 mr = WmNcMouseDown(wParam, GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam), LEFT_BUTTON); 1591 ignoreNextLBTNUP = FALSE; 1592 break; 1593 case WM_NCLBUTTONUP: 1594 mr = WmNcMouseUp(wParam, GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam), LEFT_BUTTON); 1595 break; 1596 case WM_NCRBUTTONDOWN: 1597 mr = WmNcMouseDown(wParam, GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam), RIGHT_BUTTON); 1598 break; 1599 case WM_LBUTTONUP: 1600 if (ignoreNextLBTNUP) { 1601 ignoreNextLBTNUP = FALSE; 1602 return mrDoDefault; 1603 } 1604 //fall-through 1605 case WM_LBUTTONDOWN: 1606 ignoreNextLBTNUP = FALSE; 1607 //fall-through 1608 case WM_LBUTTONDBLCLK: 1609 case WM_RBUTTONDOWN: 1610 case WM_RBUTTONDBLCLK: 1611 case WM_RBUTTONUP: 1612 case WM_MBUTTONDOWN: 1613 case WM_MBUTTONDBLCLK: 1614 case WM_MBUTTONUP: 1615 case WM_XBUTTONDBLCLK: 1616 case WM_XBUTTONDOWN: 1617 case WM_XBUTTONUP: 1618 case WM_MOUSEMOVE: 1619 case WM_MOUSEWHEEL: 1620 case WM_AWT_MOUSEENTER: 1621 case WM_AWT_MOUSEEXIT: 1622 curPos = ::GetMessagePos(); 1623 POINT myPos; 1624 myPos.x = GET_X_LPARAM(curPos); 1625 myPos.y = GET_Y_LPARAM(curPos); 1626 ::ScreenToClient(GetHWnd(), &myPos); 1627 switch(switchMessage) { 1628 case WM_AWT_MOUSEENTER: 1629 mr = WmMouseEnter(static_cast<UINT>(wParam), myPos.x, myPos.y); 1630 break; 1631 case WM_LBUTTONDOWN: 1632 case WM_LBUTTONDBLCLK: 1633 mr = WmMouseDown(static_cast<UINT>(wParam), myPos.x, myPos.y, 1634 LEFT_BUTTON); 1635 break; 1636 case WM_LBUTTONUP: 1637 mr = WmMouseUp(static_cast<UINT>(wParam), myPos.x, myPos.y, 1638 LEFT_BUTTON); 1639 break; 1640 case WM_MOUSEMOVE: 1641 mr = WmMouseMove(static_cast<UINT>(wParam), myPos.x, myPos.y); 1642 break; 1643 case WM_MBUTTONDOWN: 1644 case WM_MBUTTONDBLCLK: 1645 mr = WmMouseDown(static_cast<UINT>(wParam), myPos.x, myPos.y, 1646 MIDDLE_BUTTON); 1647 break; 1648 case WM_XBUTTONDOWN: 1649 case WM_XBUTTONDBLCLK: 1650 if (AwtToolkit::GetInstance().areExtraMouseButtonsEnabled()) { 1651 if (HIWORD(wParam) == 1) { 1652 mr = WmMouseDown(static_cast<UINT>(wParam), myPos.x, myPos.y, 1653 X1_BUTTON); 1654 } 1655 if (HIWORD(wParam) == 2) { 1656 mr = WmMouseDown(static_cast<UINT>(wParam), myPos.x, myPos.y, 1657 X2_BUTTON); 1658 } 1659 } 1660 break; 1661 case WM_XBUTTONUP: 1662 if (AwtToolkit::GetInstance().areExtraMouseButtonsEnabled()) { 1663 if (HIWORD(wParam) == 1) { 1664 mr = WmMouseUp(static_cast<UINT>(wParam), myPos.x, myPos.y, 1665 X1_BUTTON); 1666 } 1667 if (HIWORD(wParam) == 2) { 1668 mr = WmMouseUp(static_cast<UINT>(wParam), myPos.x, myPos.y, 1669 X2_BUTTON); 1670 } 1671 } 1672 break; 1673 case WM_RBUTTONDOWN: 1674 case WM_RBUTTONDBLCLK: 1675 mr = WmMouseDown(static_cast<UINT>(wParam), myPos.x, myPos.y, 1676 RIGHT_BUTTON); 1677 break; 1678 case WM_RBUTTONUP: 1679 mr = WmMouseUp(static_cast<UINT>(wParam), myPos.x, myPos.y, 1680 RIGHT_BUTTON); 1681 break; 1682 case WM_MBUTTONUP: 1683 mr = WmMouseUp(static_cast<UINT>(wParam), myPos.x, myPos.y, 1684 MIDDLE_BUTTON); 1685 break; 1686 case WM_AWT_MOUSEEXIT: 1687 mr = WmMouseExit(static_cast<UINT>(wParam), myPos.x, myPos.y); 1688 break; 1689 case WM_MOUSEWHEEL: 1690 mr = WmMouseWheel(GET_KEYSTATE_WPARAM(wParam), 1691 GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam), 1692 GET_WHEEL_DELTA_WPARAM(wParam)); 1693 break; 1694 } 1695 break; 1696 case WM_SETCURSOR: 1697 mr = mrDoDefault; 1698 if (LOWORD(lParam) == HTCLIENT) { 1699 if (AwtComponent* comp = 1700 AwtComponent::GetComponent((HWND)wParam)) { 1701 AwtCursor::UpdateCursor(comp); 1702 mr = mrConsume; 1703 } 1704 } 1705 break; 1706 1707 case WM_KEYDOWN: 1708 mr = WmKeyDown(static_cast<UINT>(wParam), 1709 LOWORD(lParam), HIWORD(lParam), FALSE); 1710 break; 1711 case WM_KEYUP: 1712 mr = WmKeyUp(static_cast<UINT>(wParam), 1713 LOWORD(lParam), HIWORD(lParam), FALSE); 1714 break; 1715 case WM_SYSKEYDOWN: 1716 mr = WmKeyDown(static_cast<UINT>(wParam), 1717 LOWORD(lParam), HIWORD(lParam), TRUE); 1718 break; 1719 case WM_SYSKEYUP: 1720 mr = WmKeyUp(static_cast<UINT>(wParam), 1721 LOWORD(lParam), HIWORD(lParam), TRUE); 1722 break; 1723 case WM_IME_SETCONTEXT: 1724 // lParam is passed as pointer and it can be modified. 1725 mr = WmImeSetContext(static_cast<BOOL>(wParam), &lParam); 1726 break; 1727 case WM_IME_NOTIFY: 1728 mr = WmImeNotify(wParam, lParam); 1729 break; 1730 case WM_IME_STARTCOMPOSITION: 1731 mr = WmImeStartComposition(); 1732 CallProxyDefWindowProc(message, wParam, lParam, retValue, mr); 1733 break; 1734 case WM_IME_ENDCOMPOSITION: 1735 mr = WmImeEndComposition(); 1736 CallProxyDefWindowProc(message, wParam, lParam, retValue, mr); 1737 break; 1738 case WM_IME_COMPOSITION: { 1739 WORD dbcschar = static_cast<WORD>(wParam); 1740 mr = WmImeComposition(dbcschar, lParam); 1741 CallProxyDefWindowProc(message, wParam, lParam, retValue, mr); 1742 break; 1743 } 1744 case WM_IME_CONTROL: 1745 case WM_IME_COMPOSITIONFULL: 1746 case WM_IME_SELECT: 1747 case WM_IME_KEYUP: 1748 case WM_IME_KEYDOWN: 1749 case WM_IME_REQUEST: 1750 CallProxyDefWindowProc(message, wParam, lParam, retValue, mr); 1751 break; 1752 case WM_CHAR: 1753 mr = WmChar(static_cast<UINT>(wParam), 1754 LOWORD(lParam), HIWORD(lParam), FALSE); 1755 break; 1756 case WM_SYSCHAR: 1757 mr = WmChar(static_cast<UINT>(wParam), 1758 LOWORD(lParam), HIWORD(lParam), TRUE); 1759 break; 1760 case WM_IME_CHAR: 1761 mr = WmIMEChar(static_cast<UINT>(wParam), 1762 LOWORD(lParam), HIWORD(lParam), FALSE); 1763 break; 1764 1765 case WM_INPUTLANGCHANGEREQUEST: { 1766 DTRACE_PRINTLN4("WM_INPUTLANGCHANGEREQUEST: hwnd = 0x%X (%s);"// 1767 "0x%08X -> 0x%08X", 1768 GetHWnd(), GetClassName(), 1769 (UINT_PTR)GetKeyboardLayout(), (UINT_PTR)lParam); 1770 // 4267428: make sure keyboard layout is turned undead. 1771 static BYTE keyboardState[AwtToolkit::KB_STATE_SIZE]; 1772 AwtToolkit::GetKeyboardState(keyboardState); 1773 WORD ignored; 1774 ::ToAsciiEx(VK_SPACE, ::MapVirtualKey(VK_SPACE, 0), 1775 keyboardState, &ignored, 0, GetKeyboardLayout()); 1776 1777 // Set this flag to block ActivateKeyboardLayout from 1778 // WInputMethod.activate() 1779 g_bUserHasChangedInputLang = TRUE; 1780 CallProxyDefWindowProc(message, wParam, lParam, retValue, mr); 1781 break; 1782 } 1783 case WM_INPUTLANGCHANGE: 1784 DTRACE_PRINTLN3("WM_INPUTLANGCHANGE: hwnd = 0x%X (%s);"// 1785 "new = 0x%08X", 1786 GetHWnd(), GetClassName(), (UINT)lParam); 1787 mr = WmInputLangChange(static_cast<UINT>(wParam), reinterpret_cast<HKL>(lParam)); 1788 CallProxyDefWindowProc(message, wParam, lParam, retValue, mr); 1789 // should return non-zero if we process this message 1790 retValue = 1; 1791 break; 1792 1793 case WM_AWT_FORWARD_CHAR: 1794 mr = WmForwardChar(LOWORD(wParam), lParam, HIWORD(wParam)); 1795 break; 1796 1797 case WM_AWT_FORWARD_BYTE: 1798 mr = HandleEvent( (MSG *) lParam, (BOOL) wParam); 1799 break; 1800 1801 case WM_PASTE: 1802 mr = WmPaste(); 1803 break; 1804 case WM_TIMER: 1805 mr = WmTimer(wParam); 1806 break; 1807 1808 case WM_COMMAND: 1809 mr = WmCommand(LOWORD(wParam), (HWND)lParam, HIWORD(wParam)); 1810 break; 1811 case WM_COMPAREITEM: 1812 mr = WmCompareItem(static_cast<UINT>(wParam), 1813 *(COMPAREITEMSTRUCT*)lParam, retValue); 1814 break; 1815 case WM_DELETEITEM: 1816 mr = WmDeleteItem(static_cast<UINT>(wParam), 1817 *(DELETEITEMSTRUCT*)lParam); 1818 break; 1819 case WM_DRAWITEM: 1820 mr = WmDrawItem(static_cast<UINT>(wParam), 1821 *(DRAWITEMSTRUCT*)lParam); 1822 break; 1823 case WM_MEASUREITEM: 1824 mr = WmMeasureItem(static_cast<UINT>(wParam), 1825 *(MEASUREITEMSTRUCT*)lParam); 1826 break; 1827 1828 case WM_AWT_HANDLE_EVENT: 1829 mr = HandleEvent( (MSG *) lParam, (BOOL) wParam); 1830 break; 1831 1832 case WM_PRINT: 1833 mr = WmPrint((HDC)wParam, lParam); 1834 break; 1835 case WM_PRINTCLIENT: 1836 mr = WmPrintClient((HDC)wParam, lParam); 1837 break; 1838 1839 case WM_NCCALCSIZE: 1840 mr = WmNcCalcSize((BOOL)wParam, (LPNCCALCSIZE_PARAMS)lParam, 1841 retValue); 1842 break; 1843 case WM_NCPAINT: 1844 mr = WmNcPaint((HRGN)wParam); 1845 break; 1846 case WM_NCHITTEST: 1847 mr = WmNcHitTest(LOWORD(lParam), HIWORD(lParam), retValue); 1848 break; 1849 1850 case WM_AWT_RESHAPE_COMPONENT: { 1851 RECT* r = (RECT*)lParam; 1852 WPARAM checkEmbedded = wParam; 1853 if (checkEmbedded == CHECK_EMBEDDED && IsEmbeddedFrame()) { 1854 ::OffsetRect(r, -r->left, -r->top); 1855 } 1856 Reshape(r->left, r->top, r->right - r->left, r->bottom - r->top); 1857 delete r; 1858 mr = mrConsume; 1859 break; 1860 } 1861 1862 case WM_AWT_SETALWAYSONTOP: { 1863 AwtWindow* w = (AwtWindow*)lParam; 1864 BOOL value = (BOOL)wParam; 1865 UINT flags = SWP_NOMOVE | SWP_NOSIZE; 1866 // transient windows shouldn't change the owner window's position in the z-order 1867 if (w->IsRetainingHierarchyZOrder()) { 1868 flags |= SWP_NOOWNERZORDER; 1869 } 1870 ::SetWindowPos(w->GetHWnd(), (value != 0 ? HWND_TOPMOST : HWND_NOTOPMOST), 1871 0,0,0,0, flags); 1872 break; 1873 } 1874 1875 case WM_AWT_BEGIN_VALIDATE: 1876 BeginValidate(); 1877 mr = mrConsume; 1878 break; 1879 case WM_AWT_END_VALIDATE: 1880 EndValidate(); 1881 mr = mrConsume; 1882 break; 1883 1884 case WM_PALETTEISCHANGING: 1885 mr = WmPaletteIsChanging((HWND)wParam); 1886 mr = mrDoDefault; 1887 break; 1888 case WM_QUERYNEWPALETTE: 1889 mr = WmQueryNewPalette(retValue); 1890 break; 1891 case WM_PALETTECHANGED: 1892 mr = WmPaletteChanged((HWND)wParam); 1893 break; 1894 case WM_STYLECHANGED: 1895 mr = WmStyleChanged(static_cast<int>(wParam), (LPSTYLESTRUCT)lParam); 1896 break; 1897 case WM_SETTINGCHANGE: 1898 CheckFontSmoothingSettings(NULL); 1899 mr = WmSettingChange(static_cast<UINT>(wParam), (LPCTSTR)lParam); 1900 break; 1901 case WM_CONTEXTMENU: 1902 mr = WmContextMenu((HWND)wParam, 1903 GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam)); 1904 break; 1905 1906 /* 1907 * These messages are used to route Win32 calls to the 1908 * creating thread, since these calls fail unless executed 1909 * there. 1910 */ 1911 case WM_AWT_COMPONENT_SHOW: 1912 Show(); 1913 mr = mrConsume; 1914 break; 1915 case WM_AWT_COMPONENT_HIDE: 1916 Hide(); 1917 mr = mrConsume; 1918 break; 1919 1920 case WM_AWT_COMPONENT_SETFOCUS: 1921 if ((BOOL)wParam) { 1922 retValue = SynthesizeWmSetFocus(GetHWnd(), NULL); 1923 } else { 1924 retValue = SynthesizeWmKillFocus(GetHWnd(), NULL); 1925 } 1926 mr = mrConsume; 1927 break; 1928 case WM_AWT_WINDOW_SETACTIVE: 1929 retValue = (LRESULT)((AwtWindow*)this)->AwtSetActiveWindow((BOOL)wParam); 1930 mr = mrConsume; 1931 break; 1932 1933 case WM_AWT_SET_SCROLL_INFO: { 1934 SCROLLINFO *si = (SCROLLINFO *) lParam; 1935 ::SetScrollInfo(GetHWnd(), (int) wParam, si, TRUE); 1936 delete si; 1937 mr = mrConsume; 1938 break; 1939 } 1940 case WM_AWT_CREATE_PRINTED_PIXELS: { 1941 CreatePrintedPixelsStruct* cpps = (CreatePrintedPixelsStruct*)wParam; 1942 SIZE loc = { cpps->srcx, cpps->srcy }; 1943 SIZE size = { cpps->srcw, cpps->srch }; 1944 retValue = (LRESULT)CreatePrintedPixels(loc, size, cpps->alpha); 1945 mr = mrConsume; 1946 break; 1947 } 1948 case WM_UNDOCUMENTED_CLICKMENUBAR: 1949 { 1950 if (::IsWindow(AwtWindow::GetModalBlocker(GetHWnd()))) { 1951 mr = mrConsume; 1952 } 1953 } 1954 } 1955 1956 /* 1957 * If not a specific Consume, it was a specific DoDefault, or a 1958 * PassAlong (since the default is the next in chain), then call the 1959 * default proc. 1960 */ 1961 if (mr != mrConsume) { 1962 retValue = DefWindowProc(message, wParam, lParam); 1963 } 1964 1965 return retValue; 1966 } 1967 /* 1968 * Call this instance's default window proc, or if none set, call the stock 1969 * Window's one. 1970 */ 1971 LRESULT AwtComponent::DefWindowProc(UINT msg, WPARAM wParam, LPARAM lParam) 1972 { 1973 return ComCtl32Util::GetInstance().DefWindowProc(m_DefWindowProc, GetHWnd(), msg, wParam, lParam); 1974 } 1975 1976 /* 1977 * This message should only be received when a window is destroyed by 1978 * Windows, and not Java. Window termination has been reworked so 1979 * this method should never be called during termination. 1980 */ 1981 MsgRouting AwtComponent::WmDestroy() 1982 { 1983 return mrConsume; 1984 } 1985 1986 /* 1987 * This message should only be received when a window is destroyed by 1988 * Windows, and not Java. It is sent only after child windows were destroyed. 1989 */ 1990 MsgRouting AwtComponent::WmNcDestroy() 1991 { 1992 if (m_peerObject != NULL) { // is not being terminating 1993 // Stay in this handler until AwtComponent::Dispose is called. 1994 m_bPauseDestroy = TRUE; 1995 1996 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); 1997 // Post invocation event for WObjectPeer.dispose to EDT 1998 env->CallVoidMethod(m_peerObject, AwtComponent::disposeLaterMID); 1999 // Wait until AwtComponent::Dispose is called 2000 AwtToolkit::GetInstance().PumpToDestroy(this); 2001 } 2002 2003 return mrConsume; 2004 } 2005 2006 MsgRouting AwtComponent::WmGetMinMaxInfo(LPMINMAXINFO lpmmi) 2007 { 2008 return mrDoDefault; 2009 } 2010 2011 MsgRouting AwtComponent::WmMove(int x, int y) 2012 { 2013 SetDrawState(GetDrawState() | static_cast<jint>(JAWT_LOCK_BOUNDS_CHANGED) 2014 | static_cast<jint>(JAWT_LOCK_CLIP_CHANGED)); 2015 return mrDoDefault; 2016 } 2017 2018 MsgRouting AwtComponent::WmSize(UINT type, int w, int h) 2019 { 2020 SetDrawState(GetDrawState() | static_cast<jint>(JAWT_LOCK_BOUNDS_CHANGED) 2021 | static_cast<jint>(JAWT_LOCK_CLIP_CHANGED)); 2022 return mrDoDefault; 2023 } 2024 2025 MsgRouting AwtComponent::WmSizing() 2026 { 2027 return mrDoDefault; 2028 } 2029 2030 MsgRouting AwtComponent::WmSysCommand(UINT uCmdType, int xPos, int yPos) 2031 { 2032 return mrDoDefault; 2033 } 2034 2035 MsgRouting AwtComponent::WmExitSizeMove() 2036 { 2037 return mrDoDefault; 2038 } 2039 2040 MsgRouting AwtComponent::WmEnterMenuLoop(BOOL isTrackPopupMenu) 2041 { 2042 return mrDoDefault; 2043 } 2044 2045 MsgRouting AwtComponent::WmExitMenuLoop(BOOL isTrackPopupMenu) 2046 { 2047 return mrDoDefault; 2048 } 2049 2050 MsgRouting AwtComponent::WmShowWindow(BOOL show, UINT status) 2051 { 2052 return mrDoDefault; 2053 } 2054 2055 MsgRouting AwtComponent::WmSetFocus(HWND hWndLostFocus) 2056 { 2057 m_wheelRotationAmount = 0; 2058 return mrDoDefault; 2059 } 2060 2061 MsgRouting AwtComponent::WmKillFocus(HWND hWndGotFocus) 2062 { 2063 m_wheelRotationAmount = 0; 2064 return mrDoDefault; 2065 } 2066 2067 MsgRouting AwtComponent::WmCtlColor(HDC hDC, HWND hCtrl, 2068 UINT ctlColor, HBRUSH& retBrush) 2069 { 2070 AwtComponent* child = AwtComponent::GetComponent(hCtrl); 2071 if (child) { 2072 ::SetBkColor(hDC, child->GetBackgroundColor()); 2073 ::SetTextColor(hDC, child->GetColor()); 2074 retBrush = child->GetBackgroundBrush(); 2075 return mrConsume; 2076 } 2077 return mrDoDefault; 2078 /* 2079 switch (ctlColor) { 2080 case CTLCOLOR_MSGBOX: 2081 case CTLCOLOR_EDIT: 2082 case CTLCOLOR_LISTBOX: 2083 case CTLCOLOR_BTN: 2084 case CTLCOLOR_DLG: 2085 case CTLCOLOR_SCROLLBAR: 2086 case CTLCOLOR_STATIC: 2087 } 2088 */ 2089 } 2090 2091 MsgRouting AwtComponent::WmHScroll(UINT scrollCode, UINT pos, 2092 HWND hScrollbar) { 2093 if (hScrollbar && hScrollbar != GetHWnd()) { 2094 /* the last test should never happen */ 2095 AwtComponent* sb = GetComponent(hScrollbar); 2096 if (sb) { 2097 sb->WmHScroll(scrollCode, pos, hScrollbar); 2098 } 2099 } 2100 return mrDoDefault; 2101 } 2102 2103 MsgRouting AwtComponent::WmVScroll(UINT scrollCode, UINT pos, HWND hScrollbar) 2104 { 2105 if (hScrollbar && hScrollbar != GetHWnd()) { 2106 /* the last test should never happen */ 2107 AwtComponent* sb = GetComponent(hScrollbar); 2108 if (sb) { 2109 sb->WmVScroll(scrollCode, pos, hScrollbar); 2110 } 2111 } 2112 return mrDoDefault; 2113 } 2114 2115 namespace TimeHelper { 2116 // Sometimes the message belongs to another event queue and 2117 // GetMessageTime() may return wrong non-zero value (the case is 2118 // the TrayIcon peer). Using TimeHelper::windowsToUTC(::GetTickCount()) 2119 // could help there. 2120 static DWORD getMessageTimeWindows(){ 2121 DWORD time = ::GetMessageTime(); 2122 // The following 'if' seems to be a unneeded hack. 2123 // Consider removing it. 2124 if (time == 0) { 2125 time = ::GetTickCount(); 2126 } 2127 return time; 2128 } 2129 2130 jlong getMessageTimeUTC() { 2131 return windowsToUTC(getMessageTimeWindows()); 2132 } 2133 2134 // If calling order of GetTickCount and JVM_CurrentTimeMillis 2135 // is swapped, it would sometimes give different result. 2136 // Anyway, we would not always have determinism 2137 // and sortedness of time conversion here (due to Windows's 2138 // timers peculiarities). Having some euristic algorithm might 2139 // help here. 2140 jlong windowsToUTC(DWORD windowsTime) { 2141 jlong offset = ::GetTickCount() - windowsTime; 2142 jlong jvm_time = ::JVM_CurrentTimeMillis(NULL, 0); 2143 return jvm_time - offset; 2144 } 2145 } //TimeHelper 2146 2147 MsgRouting AwtComponent::WmPaint(HDC) 2148 { 2149 /* Get the rectangle that covers all update regions, if any exist. */ 2150 RECT r; 2151 if (::GetUpdateRect(GetHWnd(), &r, FALSE)) { 2152 if ((r.right-r.left) > 0 && (r.bottom-r.top) > 0 && 2153 m_peerObject != NULL && m_callbacksEnabled) { 2154 /* 2155 * Always call handlePaint, because the underlying control 2156 * will have painted itself (the "background") before any 2157 * paint method is called. 2158 */ 2159 DoCallback("handlePaint", "(IIII)V", 2160 r.left, r.top, r.right-r.left, r.bottom-r.top); 2161 } 2162 } 2163 return mrDoDefault; 2164 } 2165 2166 void AwtComponent::PaintUpdateRgn(const RECT *insets) 2167 { 2168 // Fix 4530093: Don't Validate if can't actually paint 2169 if (m_peerObject == NULL || !m_callbacksEnabled) { 2170 2171 // Fix 4745222: If we dont ValidateRgn, windows will keep sending 2172 // WM_PAINT messages until we do. This causes java to go into 2173 // a tight loop that increases CPU to 100% and starves main 2174 // thread which needs to complete initialization, but cant. 2175 ::ValidateRgn(GetHWnd(), NULL); 2176 2177 return; 2178 } 2179 2180 HRGN rgn = ::CreateRectRgn(0,0,1,1); 2181 int updated = ::GetUpdateRgn(GetHWnd(), rgn, FALSE); 2182 /* 2183 * Now remove all update regions from this window -- do it 2184 * here instead of after the Java upcall, in case any new 2185 * updating is requested. 2186 */ 2187 ::ValidateRgn(GetHWnd(), NULL); 2188 2189 if (updated == COMPLEXREGION || updated == SIMPLEREGION) { 2190 if (insets != NULL) { 2191 ::OffsetRgn(rgn, insets->left, insets->top); 2192 } 2193 DWORD size = ::GetRegionData(rgn, 0, NULL); 2194 if (size == 0) { 2195 ::DeleteObject((HGDIOBJ)rgn); 2196 return; 2197 } 2198 char* buffer = new char[size]; // safe because sizeof(char)==1 2199 memset(buffer, 0, size); 2200 LPRGNDATA rgndata = (LPRGNDATA)buffer; 2201 rgndata->rdh.dwSize = sizeof(RGNDATAHEADER); 2202 rgndata->rdh.iType = RDH_RECTANGLES; 2203 int retCode = ::GetRegionData(rgn, size, rgndata); 2204 VERIFY(retCode); 2205 if (retCode == 0) { 2206 delete [] buffer; 2207 ::DeleteObject((HGDIOBJ)rgn); 2208 return; 2209 } 2210 /* 2211 * Updating rects are divided into mostly vertical and mostly horizontal 2212 * Each group is united together and if not empty painted separately 2213 */ 2214 RECT* r = (RECT*)(buffer + rgndata->rdh.dwSize); 2215 RECT* un[2] = {0, 0}; 2216 DWORD i; 2217 for (i = 0; i < rgndata->rdh.nCount; i++, r++) { 2218 int width = r->right-r->left; 2219 int height = r->bottom-r->top; 2220 if (width > 0 && height > 0) { 2221 int toAdd = (width > height) ? 0: 1; 2222 if (un[toAdd] != 0) { 2223 ::UnionRect(un[toAdd], un[toAdd], r); 2224 } else { 2225 un[toAdd] = r; 2226 } 2227 } 2228 } 2229 for(i = 0; i < 2; i++) { 2230 if (un[i] != 0) { 2231 DoCallback("handleExpose", "(IIII)V", un[i]->left, un[i]->top, 2232 un[i]->right-un[i]->left, un[i]->bottom-un[i]->top); 2233 } 2234 } 2235 delete [] buffer; 2236 } 2237 ::DeleteObject((HGDIOBJ)rgn); 2238 } 2239 2240 MsgRouting AwtComponent::WmMouseEnter(UINT flags, int x, int y) 2241 { 2242 SendMouseEvent(java_awt_event_MouseEvent_MOUSE_ENTERED, 2243 TimeHelper::getMessageTimeUTC(), x, y, GetJavaModifiers(), 0, JNI_FALSE); 2244 if ((flags & ALL_MK_BUTTONS) == 0) { 2245 AwtCursor::UpdateCursor(this); 2246 } 2247 sm_cursorOn = GetHWnd(); 2248 return mrConsume; /* Don't pass our synthetic event on! */ 2249 } 2250 2251 MSG* 2252 AwtComponent::CreateMessage(UINT message, WPARAM wParam, LPARAM lParam, 2253 int x = 0, int y = 0) 2254 { 2255 MSG* pMsg = new MSG; 2256 InitMessage(pMsg, message, wParam, lParam, x, y); 2257 return pMsg; 2258 } 2259 2260 2261 jint 2262 AwtComponent::GetDrawState(HWND hwnd) { 2263 return (jint)(INT_PTR)(::GetProp(hwnd, DrawingStateProp)); 2264 } 2265 2266 void 2267 AwtComponent::SetDrawState(HWND hwnd, jint state) { 2268 ::SetProp(hwnd, DrawingStateProp, (HANDLE)(INT_PTR)state); 2269 } 2270 2271 void 2272 AwtComponent::InitMessage(MSG* msg, UINT message, WPARAM wParam, LPARAM lParam, 2273 int x = 0, int y = 0) 2274 { 2275 msg->message = message; 2276 msg->wParam = wParam; 2277 msg->lParam = lParam; 2278 msg->time = TimeHelper::getMessageTimeWindows(); 2279 msg->pt.x = x; 2280 msg->pt.y = y; 2281 } 2282 2283 MsgRouting AwtComponent::WmNcMouseDown(WPARAM hitTest, int x, int y, int button) { 2284 return mrDoDefault; 2285 } 2286 MsgRouting AwtComponent::WmNcMouseUp(WPARAM hitTest, int x, int y, int button) { 2287 return mrDoDefault; 2288 } 2289 2290 MsgRouting AwtComponent::WmWindowPosChanging(LPARAM windowPos) { 2291 return mrDoDefault; 2292 } 2293 MsgRouting AwtComponent::WmWindowPosChanged(LPARAM windowPos) { 2294 return mrDoDefault; 2295 } 2296 2297 /* Double-click variables. */ 2298 static jlong multiClickTime = ::GetDoubleClickTime(); 2299 static int multiClickMaxX = ::GetSystemMetrics(SM_CXDOUBLECLK); 2300 static int multiClickMaxY = ::GetSystemMetrics(SM_CYDOUBLECLK); 2301 static AwtComponent* lastClickWnd = NULL; 2302 static jlong lastTime = 0; 2303 static int lastClickX = 0; 2304 static int lastClickY = 0; 2305 static int lastButton = 0; 2306 static int clickCount = 0; 2307 2308 // A static method that makes the clickCount available in the derived classes 2309 // overriding WmMouseDown(). 2310 int AwtComponent::GetClickCount() 2311 { 2312 return clickCount; 2313 } 2314 2315 MsgRouting AwtComponent::WmMouseDown(UINT flags, int x, int y, int button) 2316 { 2317 jlong now = TimeHelper::getMessageTimeUTC(); 2318 2319 if (lastClickWnd == this && 2320 lastButton == button && 2321 (now - lastTime) <= multiClickTime && 2322 abs(x - lastClickX) <= multiClickMaxX && 2323 abs(y - lastClickY) <= multiClickMaxY) 2324 { 2325 clickCount++; 2326 } else { 2327 clickCount = 1; 2328 lastClickWnd = this; 2329 lastButton = button; 2330 lastClickX = x; 2331 lastClickY = y; 2332 } 2333 /* 2334 *Set appropriate bit of the mask on WM_MOUSE_DOWN message. 2335 */ 2336 m_mouseButtonClickAllowed |= GetButtonMK(button); 2337 lastTime = now; 2338 2339 MSG msg; 2340 InitMessage(&msg, lastMessage, flags, MAKELPARAM(x, y), x, y); 2341 2342 AwtWindow *toplevel = GetContainer(); 2343 if (toplevel && !toplevel->IsSimpleWindow()) { 2344 /* 2345 * The frame should be focused by click in case it is 2346 * the active window but not the focused window. See 6886678. 2347 */ 2348 if (toplevel->GetHWnd() == ::GetActiveWindow() && 2349 toplevel->GetHWnd() != AwtComponent::GetFocusedWindow()) 2350 { 2351 toplevel->AwtSetActiveWindow(); 2352 } 2353 } 2354 2355 SendMouseEvent(java_awt_event_MouseEvent_MOUSE_PRESSED, now, x, y, 2356 GetJavaModifiers(), clickCount, JNI_FALSE, 2357 GetButton(button), &msg); 2358 /* 2359 * NOTE: this call is intentionally placed after all other code, 2360 * since AwtComponent::WmMouseDown() assumes that the cached id of the 2361 * latest retrieved message (see lastMessage in awt_Component.cpp) 2362 * matches the mouse message being processed. 2363 * SetCapture() sends WM_CAPTURECHANGED and breaks that 2364 * assumption. 2365 */ 2366 SetDragCapture(flags); 2367 2368 AwtWindow * owner = (AwtWindow*)GetComponent(GetTopLevelParentForWindow(GetHWnd())); 2369 if (AwtWindow::GetGrabbedWindow() != NULL && owner != NULL) { 2370 if (!AwtWindow::GetGrabbedWindow()->IsOneOfOwnersOf(owner)) { 2371 AwtWindow::GetGrabbedWindow()->Ungrab(); 2372 } 2373 } 2374 return mrConsume; 2375 } 2376 2377 MsgRouting AwtComponent::WmMouseUp(UINT flags, int x, int y, int button) 2378 { 2379 MSG msg; 2380 InitMessage(&msg, lastMessage, flags, MAKELPARAM(x, y), x, y); 2381 2382 SendMouseEvent(java_awt_event_MouseEvent_MOUSE_RELEASED, TimeHelper::getMessageTimeUTC(), 2383 x, y, GetJavaModifiers(), clickCount, 2384 (GetButton(button) == java_awt_event_MouseEvent_BUTTON3 ? 2385 TRUE : FALSE), GetButton(button), &msg); 2386 /* 2387 * If no movement, then report a click following the button release. 2388 * When WM_MOUSEUP comes to a window without previous WM_MOUSEDOWN, 2389 * spurous MOUSE_CLICK is about to happen. See 6430553. 2390 */ 2391 if ((m_mouseButtonClickAllowed & GetButtonMK(button)) != 0) { //CLICK allowed 2392 SendMouseEvent(java_awt_event_MouseEvent_MOUSE_CLICKED, 2393 TimeHelper::getMessageTimeUTC(), x, y, GetJavaModifiers(), 2394 clickCount, JNI_FALSE, GetButton(button)); 2395 } 2396 // Exclude button from allowed to generate CLICK messages 2397 m_mouseButtonClickAllowed &= ~GetButtonMK(button); 2398 2399 if ((flags & ALL_MK_BUTTONS) == 0) { 2400 // only update if all buttons have been released 2401 AwtCursor::UpdateCursor(this); 2402 } 2403 /* 2404 * NOTE: this call is intentionally placed after all other code, 2405 * since AwtComponent::WmMouseUp() assumes that the cached id of the 2406 * latest retrieved message (see lastMessage in awt_Component.cpp) 2407 * matches the mouse message being processed. 2408 * ReleaseCapture() sends WM_CAPTURECHANGED and breaks that 2409 * assumption. 2410 */ 2411 ReleaseDragCapture(flags); 2412 2413 return mrConsume; 2414 } 2415 2416 MsgRouting AwtComponent::WmMouseMove(UINT flags, int x, int y) 2417 { 2418 static AwtComponent* lastComp = NULL; 2419 static int lastX = 0; 2420 static int lastY = 0; 2421 2422 /* 2423 * Only report mouse move and drag events if a move or drag 2424 * actually happened -- Windows sends a WM_MOUSEMOVE in case the 2425 * app wants to modify the cursor. 2426 */ 2427 if (lastComp != this || x != lastX || y != lastY) { 2428 lastComp = this; 2429 lastX = x; 2430 lastY = y; 2431 BOOL extraButtonsEnabled = AwtToolkit::GetInstance().areExtraMouseButtonsEnabled(); 2432 if (((flags & (ALL_MK_BUTTONS)) != 0) || 2433 (extraButtonsEnabled && (flags & (X_BUTTONS)) != 0)) 2434 // if (( extraButtonsEnabled && ( (flags & (ALL_MK_BUTTONS | X_BUTTONS)) != 0 )) || 2435 // ( !extraButtonsEnabled && (((flags & (ALL_MK_BUTTONS)) != 0 )) && ((flags & (X_BUTTONS)) == 0) )) 2436 { 2437 // 6404008 : if Dragged event fired we shouldn't fire 2438 // Clicked event: m_firstDragSent set to TRUE. 2439 // This is a partial backout of 5039416 fix. 2440 MSG msg; 2441 InitMessage(&msg, lastMessage, flags, MAKELPARAM(x, y), x, y); 2442 SendMouseEvent(java_awt_event_MouseEvent_MOUSE_DRAGGED, TimeHelper::getMessageTimeUTC(), x, y, 2443 GetJavaModifiers(), 0, JNI_FALSE, 2444 java_awt_event_MouseEvent_NOBUTTON, &msg); 2445 //dragging means no more CLICKs until next WM_MOUSE_DOWN/WM_MOUSE_UP message sequence 2446 m_mouseButtonClickAllowed = 0; 2447 } else { 2448 MSG msg; 2449 InitMessage(&msg, lastMessage, flags, MAKELPARAM(x, y), x, y); 2450 SendMouseEvent(java_awt_event_MouseEvent_MOUSE_MOVED, TimeHelper::getMessageTimeUTC(), x, y, 2451 GetJavaModifiers(), 0, JNI_FALSE, 2452 java_awt_event_MouseEvent_NOBUTTON, &msg); 2453 } 2454 } 2455 2456 return mrConsume; 2457 } 2458 2459 MsgRouting AwtComponent::WmMouseExit(UINT flags, int x, int y) 2460 { 2461 SendMouseEvent(java_awt_event_MouseEvent_MOUSE_EXITED, TimeHelper::getMessageTimeUTC(), x, 2462 y, GetJavaModifiers(), 0, JNI_FALSE); 2463 sm_cursorOn = NULL; 2464 return mrConsume; /* Don't pass our synthetic event on! */ 2465 } 2466 2467 MsgRouting AwtComponent::WmMouseWheel(UINT flags, int x, int y, 2468 int wheelRotation) 2469 { 2470 // convert coordinates to be Component-relative, not screen relative 2471 // for wheeling when outside the window, this works similar to 2472 // coordinates during a drag 2473 POINT eventPt; 2474 eventPt.x = x; 2475 eventPt.y = y; 2476 DTRACE_PRINT2(" original coords: %i,%i\n", x, y); 2477 ::ScreenToClient(GetHWnd(), &eventPt); 2478 DTRACE_PRINT2(" new coords: %i,%i\n\n", eventPt.x, eventPt.y); 2479 2480 // set some defaults 2481 jint scrollType = java_awt_event_MouseWheelEvent_WHEEL_UNIT_SCROLL; 2482 jint scrollLines = 3; 2483 2484 BOOL result; 2485 UINT platformLines; 2486 2487 m_wheelRotationAmount += wheelRotation; 2488 2489 // AWT interprets wheel rotation differently than win32, so we need to 2490 // decode wheel amount. 2491 jint roundedWheelRotation = m_wheelRotationAmount / (-1 * WHEEL_DELTA); 2492 jdouble preciseWheelRotation = (jdouble) wheelRotation / (-1 * WHEEL_DELTA); 2493 2494 MSG msg; 2495 result = ::SystemParametersInfo(SPI_GETWHEELSCROLLLINES, 0, 2496 &platformLines, 0); 2497 InitMessage(&msg, lastMessage, MAKEWPARAM(flags, wheelRotation), 2498 MAKELPARAM(x, y)); 2499 2500 if (result) { 2501 if (platformLines == WHEEL_PAGESCROLL) { 2502 scrollType = java_awt_event_MouseWheelEvent_WHEEL_BLOCK_SCROLL; 2503 scrollLines = 1; 2504 } 2505 else { 2506 scrollType = java_awt_event_MouseWheelEvent_WHEEL_UNIT_SCROLL; 2507 scrollLines = platformLines; 2508 } 2509 } 2510 2511 DTRACE_PRINTLN("calling SendMouseWheelEvent"); 2512 2513 SendMouseWheelEvent(java_awt_event_MouseEvent_MOUSE_WHEEL, TimeHelper::getMessageTimeUTC(), 2514 eventPt.x, eventPt.y, GetJavaModifiers(), 0, 0, scrollType, 2515 scrollLines, roundedWheelRotation, preciseWheelRotation, &msg); 2516 2517 m_wheelRotationAmount %= WHEEL_DELTA; 2518 // this message could be propagated up to the parent chain 2519 // by the mouse message post processors 2520 return mrConsume; 2521 } 2522 2523 jint AwtComponent::GetKeyLocation(UINT wkey, UINT flags) { 2524 // Rector+Newcomer page 413 2525 // The extended keys are the Alt and Control on the right of 2526 // the space bar, the non-Numpad arrow keys, the non-Numpad 2527 // Insert, PageUp, etc. keys, and the Numpad Divide and Enter keys. 2528 // Note that neither Shift key is extended. 2529 // Although not listed in Rector+Newcomer, both Windows keys 2530 // (91 and 92) are extended keys, the Context Menu key 2531 // (property key or application key - 93) is extended, 2532 // and so is the NumLock key. 2533 2534 // wkey is the wParam, flags is the HIWORD of the lParam 2535 2536 // "Extended" bit is 24th in lParam, so it's 8th in flags = HIWORD(lParam) 2537 BOOL extended = ((1<<8) & flags); 2538 2539 if (IsNumPadKey(wkey, extended)) { 2540 return java_awt_event_KeyEvent_KEY_LOCATION_NUMPAD; 2541 } 2542 2543 switch (wkey) { 2544 case VK_SHIFT: 2545 return AwtComponent::GetShiftKeyLocation(wkey, flags); 2546 case VK_CONTROL: // fall through 2547 case VK_MENU: 2548 if (extended) { 2549 return java_awt_event_KeyEvent_KEY_LOCATION_RIGHT; 2550 } else { 2551 return java_awt_event_KeyEvent_KEY_LOCATION_LEFT; 2552 } 2553 case VK_LWIN: 2554 return java_awt_event_KeyEvent_KEY_LOCATION_LEFT; 2555 case VK_RWIN: 2556 return java_awt_event_KeyEvent_KEY_LOCATION_RIGHT; 2557 default: 2558 break; 2559 } 2560 2561 // REMIND: if we add keycodes for the windows keys, we'll have to 2562 // include left/right discrimination code for them. 2563 2564 return java_awt_event_KeyEvent_KEY_LOCATION_STANDARD; 2565 } 2566 2567 jint AwtComponent::GetShiftKeyLocation(UINT vkey, UINT flags) 2568 { 2569 // init scancodes to safe values 2570 UINT leftShiftScancode = 0; 2571 UINT rightShiftScancode = 0; 2572 2573 // First 8 bits of flags is the scancode 2574 UINT keyScanCode = flags & 0xFF; 2575 2576 DTRACE_PRINTLN3( 2577 "AwtComponent::GetShiftKeyLocation vkey = %d = 0x%x scan = %d", 2578 vkey, vkey, keyScanCode); 2579 2580 leftShiftScancode = ::MapVirtualKey(VK_LSHIFT, 0); 2581 rightShiftScancode = ::MapVirtualKey(VK_RSHIFT, 0); 2582 2583 if (keyScanCode == leftShiftScancode) { 2584 return java_awt_event_KeyEvent_KEY_LOCATION_LEFT; 2585 } 2586 if (keyScanCode == rightShiftScancode) { 2587 return java_awt_event_KeyEvent_KEY_LOCATION_RIGHT; 2588 } 2589 2590 DASSERT(false); 2591 // Note: the above should not fail on NT (or 2000) 2592 2593 // default value 2594 return java_awt_event_KeyEvent_KEY_LOCATION_LEFT; 2595 } 2596 2597 /* Returns Java extended InputEvent modifieres. 2598 * Since ::GetKeyState returns current state and Java modifiers represent 2599 * state before event, modifier on changed key are inverted. 2600 */ 2601 jint 2602 AwtComponent::GetJavaModifiers() 2603 { 2604 jint modifiers = 0; 2605 2606 if (HIBYTE(::GetKeyState(VK_CONTROL)) != 0) { 2607 modifiers |= java_awt_event_InputEvent_CTRL_DOWN_MASK; 2608 } 2609 if (HIBYTE(::GetKeyState(VK_SHIFT)) != 0) { 2610 modifiers |= java_awt_event_InputEvent_SHIFT_DOWN_MASK; 2611 } 2612 if (HIBYTE(::GetKeyState(VK_MENU)) != 0) { 2613 modifiers |= java_awt_event_InputEvent_ALT_DOWN_MASK; 2614 } 2615 if (HIBYTE(::GetKeyState(VK_MBUTTON)) != 0) { 2616 modifiers |= java_awt_event_InputEvent_BUTTON2_DOWN_MASK; 2617 } 2618 if (HIBYTE(::GetKeyState(VK_RBUTTON)) != 0) { 2619 modifiers |= java_awt_event_InputEvent_BUTTON3_DOWN_MASK; 2620 } 2621 if (HIBYTE(::GetKeyState(VK_LBUTTON)) != 0) { 2622 modifiers |= java_awt_event_InputEvent_BUTTON1_DOWN_MASK; 2623 } 2624 2625 if (HIBYTE(::GetKeyState(VK_XBUTTON1)) != 0) { 2626 modifiers |= masks[3]; 2627 } 2628 if (HIBYTE(::GetKeyState(VK_XBUTTON2)) != 0) { 2629 modifiers |= masks[4]; 2630 } 2631 return modifiers; 2632 } 2633 2634 jint 2635 AwtComponent::GetButton(int mouseButton) 2636 { 2637 /* Mouse buttons are already set correctly for left/right handedness */ 2638 switch(mouseButton) { 2639 case LEFT_BUTTON: 2640 return java_awt_event_MouseEvent_BUTTON1; 2641 case MIDDLE_BUTTON: 2642 return java_awt_event_MouseEvent_BUTTON2; 2643 case RIGHT_BUTTON: 2644 return java_awt_event_MouseEvent_BUTTON3; 2645 case X1_BUTTON: //16 : 2646 //just assign 4 and 5 numbers because MouseEvent class doesn't contain const identifier for them now 2647 return 4; 2648 case X2_BUTTON: //32 2649 return 5; 2650 } 2651 return java_awt_event_MouseEvent_NOBUTTON; 2652 } 2653 2654 UINT 2655 AwtComponent::GetButtonMK(int mouseButton) 2656 { 2657 switch(mouseButton) { 2658 case LEFT_BUTTON: 2659 return MK_LBUTTON; 2660 case MIDDLE_BUTTON: 2661 return MK_MBUTTON; 2662 case RIGHT_BUTTON: 2663 return MK_RBUTTON; 2664 case X1_BUTTON: 2665 return MK_XBUTTON1; 2666 case X2_BUTTON: 2667 return MK_XBUTTON2; 2668 } 2669 return 0; 2670 } 2671 2672 // FIXME: Keyboard related stuff has grown so big and hairy that we 2673 // really need to move it into a class of its own. And, since 2674 // keyboard is a shared resource, AwtComponent is a bad place for it. 2675 2676 // These constants are defined in the Japanese version of VC++5.0, 2677 // but not the US version 2678 #ifndef VK_CONVERT 2679 #define VK_KANA 0x15 2680 #define VK_KANJI 0x19 2681 #define VK_CONVERT 0x1C 2682 #define VK_NONCONVERT 0x1D 2683 #endif 2684 2685 #ifndef VK_XBUTTON1 2686 #define VK_XBUTTON1 0x05 2687 #endif 2688 2689 #ifndef VK_XBUTTON2 2690 #define VK_XBUTTON2 0x06 2691 #endif 2692 2693 typedef struct { 2694 UINT javaKey; 2695 UINT windowsKey; 2696 } KeyMapEntry; 2697 2698 // Static table, arranged more or less spatially. 2699 KeyMapEntry keyMapTable[] = { 2700 // Modifier keys 2701 {java_awt_event_KeyEvent_VK_CAPS_LOCK, VK_CAPITAL}, 2702 {java_awt_event_KeyEvent_VK_SHIFT, VK_SHIFT}, 2703 {java_awt_event_KeyEvent_VK_CONTROL, VK_CONTROL}, 2704 {java_awt_event_KeyEvent_VK_ALT, VK_MENU}, 2705 {java_awt_event_KeyEvent_VK_NUM_LOCK, VK_NUMLOCK}, 2706 2707 // Miscellaneous Windows keys 2708 {java_awt_event_KeyEvent_VK_WINDOWS, VK_LWIN}, 2709 {java_awt_event_KeyEvent_VK_WINDOWS, VK_RWIN}, 2710 {java_awt_event_KeyEvent_VK_CONTEXT_MENU, VK_APPS}, 2711 2712 // Alphabet 2713 {java_awt_event_KeyEvent_VK_A, 'A'}, 2714 {java_awt_event_KeyEvent_VK_B, 'B'}, 2715 {java_awt_event_KeyEvent_VK_C, 'C'}, 2716 {java_awt_event_KeyEvent_VK_D, 'D'}, 2717 {java_awt_event_KeyEvent_VK_E, 'E'}, 2718 {java_awt_event_KeyEvent_VK_F, 'F'}, 2719 {java_awt_event_KeyEvent_VK_G, 'G'}, 2720 {java_awt_event_KeyEvent_VK_H, 'H'}, 2721 {java_awt_event_KeyEvent_VK_I, 'I'}, 2722 {java_awt_event_KeyEvent_VK_J, 'J'}, 2723 {java_awt_event_KeyEvent_VK_K, 'K'}, 2724 {java_awt_event_KeyEvent_VK_L, 'L'}, 2725 {java_awt_event_KeyEvent_VK_M, 'M'}, 2726 {java_awt_event_KeyEvent_VK_N, 'N'}, 2727 {java_awt_event_KeyEvent_VK_O, 'O'}, 2728 {java_awt_event_KeyEvent_VK_P, 'P'}, 2729 {java_awt_event_KeyEvent_VK_Q, 'Q'}, 2730 {java_awt_event_KeyEvent_VK_R, 'R'}, 2731 {java_awt_event_KeyEvent_VK_S, 'S'}, 2732 {java_awt_event_KeyEvent_VK_T, 'T'}, 2733 {java_awt_event_KeyEvent_VK_U, 'U'}, 2734 {java_awt_event_KeyEvent_VK_V, 'V'}, 2735 {java_awt_event_KeyEvent_VK_W, 'W'}, 2736 {java_awt_event_KeyEvent_VK_X, 'X'}, 2737 {java_awt_event_KeyEvent_VK_Y, 'Y'}, 2738 {java_awt_event_KeyEvent_VK_Z, 'Z'}, 2739 2740 // Standard numeric row 2741 {java_awt_event_KeyEvent_VK_0, '0'}, 2742 {java_awt_event_KeyEvent_VK_1, '1'}, 2743 {java_awt_event_KeyEvent_VK_2, '2'}, 2744 {java_awt_event_KeyEvent_VK_3, '3'}, 2745 {java_awt_event_KeyEvent_VK_4, '4'}, 2746 {java_awt_event_KeyEvent_VK_5, '5'}, 2747 {java_awt_event_KeyEvent_VK_6, '6'}, 2748 {java_awt_event_KeyEvent_VK_7, '7'}, 2749 {java_awt_event_KeyEvent_VK_8, '8'}, 2750 {java_awt_event_KeyEvent_VK_9, '9'}, 2751 2752 // Misc key from main block 2753 {java_awt_event_KeyEvent_VK_ENTER, VK_RETURN}, 2754 {java_awt_event_KeyEvent_VK_SPACE, VK_SPACE}, 2755 {java_awt_event_KeyEvent_VK_BACK_SPACE, VK_BACK}, 2756 {java_awt_event_KeyEvent_VK_TAB, VK_TAB}, 2757 {java_awt_event_KeyEvent_VK_ESCAPE, VK_ESCAPE}, 2758 2759 // NumPad with NumLock off & extended block (rectangular) 2760 {java_awt_event_KeyEvent_VK_INSERT, VK_INSERT}, 2761 {java_awt_event_KeyEvent_VK_DELETE, VK_DELETE}, 2762 {java_awt_event_KeyEvent_VK_HOME, VK_HOME}, 2763 {java_awt_event_KeyEvent_VK_END, VK_END}, 2764 {java_awt_event_KeyEvent_VK_PAGE_UP, VK_PRIOR}, 2765 {java_awt_event_KeyEvent_VK_PAGE_DOWN, VK_NEXT}, 2766 {java_awt_event_KeyEvent_VK_CLEAR, VK_CLEAR}, // NumPad 5 2767 2768 // NumPad with NumLock off & extended arrows block (triangular) 2769 {java_awt_event_KeyEvent_VK_LEFT, VK_LEFT}, 2770 {java_awt_event_KeyEvent_VK_RIGHT, VK_RIGHT}, 2771 {java_awt_event_KeyEvent_VK_UP, VK_UP}, 2772 {java_awt_event_KeyEvent_VK_DOWN, VK_DOWN}, 2773 2774 // NumPad with NumLock on: numbers 2775 {java_awt_event_KeyEvent_VK_NUMPAD0, VK_NUMPAD0}, 2776 {java_awt_event_KeyEvent_VK_NUMPAD1, VK_NUMPAD1}, 2777 {java_awt_event_KeyEvent_VK_NUMPAD2, VK_NUMPAD2}, 2778 {java_awt_event_KeyEvent_VK_NUMPAD3, VK_NUMPAD3}, 2779 {java_awt_event_KeyEvent_VK_NUMPAD4, VK_NUMPAD4}, 2780 {java_awt_event_KeyEvent_VK_NUMPAD5, VK_NUMPAD5}, 2781 {java_awt_event_KeyEvent_VK_NUMPAD6, VK_NUMPAD6}, 2782 {java_awt_event_KeyEvent_VK_NUMPAD7, VK_NUMPAD7}, 2783 {java_awt_event_KeyEvent_VK_NUMPAD8, VK_NUMPAD8}, 2784 {java_awt_event_KeyEvent_VK_NUMPAD9, VK_NUMPAD9}, 2785 2786 // NumPad with NumLock on 2787 {java_awt_event_KeyEvent_VK_MULTIPLY, VK_MULTIPLY}, 2788 {java_awt_event_KeyEvent_VK_ADD, VK_ADD}, 2789 {java_awt_event_KeyEvent_VK_SEPARATOR, VK_SEPARATOR}, 2790 {java_awt_event_KeyEvent_VK_SUBTRACT, VK_SUBTRACT}, 2791 {java_awt_event_KeyEvent_VK_DECIMAL, VK_DECIMAL}, 2792 {java_awt_event_KeyEvent_VK_DIVIDE, VK_DIVIDE}, 2793 2794 // Functional keys 2795 {java_awt_event_KeyEvent_VK_F1, VK_F1}, 2796 {java_awt_event_KeyEvent_VK_F2, VK_F2}, 2797 {java_awt_event_KeyEvent_VK_F3, VK_F3}, 2798 {java_awt_event_KeyEvent_VK_F4, VK_F4}, 2799 {java_awt_event_KeyEvent_VK_F5, VK_F5}, 2800 {java_awt_event_KeyEvent_VK_F6, VK_F6}, 2801 {java_awt_event_KeyEvent_VK_F7, VK_F7}, 2802 {java_awt_event_KeyEvent_VK_F8, VK_F8}, 2803 {java_awt_event_KeyEvent_VK_F9, VK_F9}, 2804 {java_awt_event_KeyEvent_VK_F10, VK_F10}, 2805 {java_awt_event_KeyEvent_VK_F11, VK_F11}, 2806 {java_awt_event_KeyEvent_VK_F12, VK_F12}, 2807 {java_awt_event_KeyEvent_VK_F13, VK_F13}, 2808 {java_awt_event_KeyEvent_VK_F14, VK_F14}, 2809 {java_awt_event_KeyEvent_VK_F15, VK_F15}, 2810 {java_awt_event_KeyEvent_VK_F16, VK_F16}, 2811 {java_awt_event_KeyEvent_VK_F17, VK_F17}, 2812 {java_awt_event_KeyEvent_VK_F18, VK_F18}, 2813 {java_awt_event_KeyEvent_VK_F19, VK_F19}, 2814 {java_awt_event_KeyEvent_VK_F20, VK_F20}, 2815 {java_awt_event_KeyEvent_VK_F21, VK_F21}, 2816 {java_awt_event_KeyEvent_VK_F22, VK_F22}, 2817 {java_awt_event_KeyEvent_VK_F23, VK_F23}, 2818 {java_awt_event_KeyEvent_VK_F24, VK_F24}, 2819 2820 {java_awt_event_KeyEvent_VK_PRINTSCREEN, VK_SNAPSHOT}, 2821 {java_awt_event_KeyEvent_VK_SCROLL_LOCK, VK_SCROLL}, 2822 {java_awt_event_KeyEvent_VK_PAUSE, VK_PAUSE}, 2823 {java_awt_event_KeyEvent_VK_CANCEL, VK_CANCEL}, 2824 {java_awt_event_KeyEvent_VK_HELP, VK_HELP}, 2825 2826 // Japanese 2827 {java_awt_event_KeyEvent_VK_CONVERT, VK_CONVERT}, 2828 {java_awt_event_KeyEvent_VK_NONCONVERT, VK_NONCONVERT}, 2829 {java_awt_event_KeyEvent_VK_INPUT_METHOD_ON_OFF, VK_KANJI}, 2830 {java_awt_event_KeyEvent_VK_ALPHANUMERIC, VK_DBE_ALPHANUMERIC}, 2831 {java_awt_event_KeyEvent_VK_KATAKANA, VK_DBE_KATAKANA}, 2832 {java_awt_event_KeyEvent_VK_HIRAGANA, VK_DBE_HIRAGANA}, 2833 {java_awt_event_KeyEvent_VK_FULL_WIDTH, VK_DBE_DBCSCHAR}, 2834 {java_awt_event_KeyEvent_VK_HALF_WIDTH, VK_DBE_SBCSCHAR}, 2835 {java_awt_event_KeyEvent_VK_ROMAN_CHARACTERS, VK_DBE_ROMAN}, 2836 2837 {java_awt_event_KeyEvent_VK_UNDEFINED, 0} 2838 }; 2839 2840 2841 // Dynamic mapping table for OEM VK codes. This table is refilled 2842 // by BuildDynamicKeyMapTable when keyboard layout is switched. 2843 // (see NT4 DDK src/input/inc/vkoem.h for OEM VK_ values). 2844 struct DynamicKeyMapEntry { 2845 UINT windowsKey; // OEM VK codes known in advance 2846 UINT javaKey; // depends on input langauge (kbd layout) 2847 }; 2848 2849 static DynamicKeyMapEntry dynamicKeyMapTable[] = { 2850 {0x00BA, java_awt_event_KeyEvent_VK_UNDEFINED}, // VK_OEM_1 2851 {0x00BB, java_awt_event_KeyEvent_VK_UNDEFINED}, // VK_OEM_PLUS 2852 {0x00BC, java_awt_event_KeyEvent_VK_UNDEFINED}, // VK_OEM_COMMA 2853 {0x00BD, java_awt_event_KeyEvent_VK_UNDEFINED}, // VK_OEM_MINUS 2854 {0x00BE, java_awt_event_KeyEvent_VK_UNDEFINED}, // VK_OEM_PERIOD 2855 {0x00BF, java_awt_event_KeyEvent_VK_UNDEFINED}, // VK_OEM_2 2856 {0x00C0, java_awt_event_KeyEvent_VK_UNDEFINED}, // VK_OEM_3 2857 {0x00DB, java_awt_event_KeyEvent_VK_UNDEFINED}, // VK_OEM_4 2858 {0x00DC, java_awt_event_KeyEvent_VK_UNDEFINED}, // VK_OEM_5 2859 {0x00DD, java_awt_event_KeyEvent_VK_UNDEFINED}, // VK_OEM_6 2860 {0x00DE, java_awt_event_KeyEvent_VK_UNDEFINED}, // VK_OEM_7 2861 {0x00DF, java_awt_event_KeyEvent_VK_UNDEFINED}, // VK_OEM_8 2862 {0x00E2, java_awt_event_KeyEvent_VK_UNDEFINED}, // VK_OEM_102 2863 {0, 0} 2864 }; 2865 2866 2867 2868 // Auxiliary tables used to fill the above dynamic table. We first 2869 // find the character for the OEM VK code using ::MapVirtualKey and 2870 // then go through these auxiliary tables to map it to Java VK code. 2871 2872 struct CharToVKEntry { 2873 WCHAR c; 2874 UINT javaKey; 2875 }; 2876 2877 static const CharToVKEntry charToVKTable[] = { 2878 {L'!', java_awt_event_KeyEvent_VK_EXCLAMATION_MARK}, 2879 {L'"', java_awt_event_KeyEvent_VK_QUOTEDBL}, 2880 {L'#', java_awt_event_KeyEvent_VK_NUMBER_SIGN}, 2881 {L'$', java_awt_event_KeyEvent_VK_DOLLAR}, 2882 {L'&', java_awt_event_KeyEvent_VK_AMPERSAND}, 2883 {L'\'', java_awt_event_KeyEvent_VK_QUOTE}, 2884 {L'(', java_awt_event_KeyEvent_VK_LEFT_PARENTHESIS}, 2885 {L')', java_awt_event_KeyEvent_VK_RIGHT_PARENTHESIS}, 2886 {L'*', java_awt_event_KeyEvent_VK_ASTERISK}, 2887 {L'+', java_awt_event_KeyEvent_VK_PLUS}, 2888 {L',', java_awt_event_KeyEvent_VK_COMMA}, 2889 {L'-', java_awt_event_KeyEvent_VK_MINUS}, 2890 {L'.', java_awt_event_KeyEvent_VK_PERIOD}, 2891 {L'/', java_awt_event_KeyEvent_VK_SLASH}, 2892 {L':', java_awt_event_KeyEvent_VK_COLON}, 2893 {L';', java_awt_event_KeyEvent_VK_SEMICOLON}, 2894 {L'<', java_awt_event_KeyEvent_VK_LESS}, 2895 {L'=', java_awt_event_KeyEvent_VK_EQUALS}, 2896 {L'>', java_awt_event_KeyEvent_VK_GREATER}, 2897 {L'@', java_awt_event_KeyEvent_VK_AT}, 2898 {L'[', java_awt_event_KeyEvent_VK_OPEN_BRACKET}, 2899 {L'\\', java_awt_event_KeyEvent_VK_BACK_SLASH}, 2900 {L']', java_awt_event_KeyEvent_VK_CLOSE_BRACKET}, 2901 {L'^', java_awt_event_KeyEvent_VK_CIRCUMFLEX}, 2902 {L'_', java_awt_event_KeyEvent_VK_UNDERSCORE}, 2903 {L'`', java_awt_event_KeyEvent_VK_BACK_QUOTE}, 2904 {L'{', java_awt_event_KeyEvent_VK_BRACELEFT}, 2905 {L'}', java_awt_event_KeyEvent_VK_BRACERIGHT}, 2906 {0x00A1, java_awt_event_KeyEvent_VK_INVERTED_EXCLAMATION_MARK}, 2907 {0x20A0, java_awt_event_KeyEvent_VK_EURO_SIGN}, // ???? 2908 {0,0} 2909 }; 2910 2911 // For dead accents some layouts return ASCII punctuation, while some 2912 // return spacing accent chars, so both should be listed. NB: MS docs 2913 // say that conversion routings return spacing accent character, not 2914 // combining. 2915 static const CharToVKEntry charToDeadVKTable[] = { 2916 {L'`', java_awt_event_KeyEvent_VK_DEAD_GRAVE}, 2917 {L'\'', java_awt_event_KeyEvent_VK_DEAD_ACUTE}, 2918 {0x00B4, java_awt_event_KeyEvent_VK_DEAD_ACUTE}, 2919 {L'^', java_awt_event_KeyEvent_VK_DEAD_CIRCUMFLEX}, 2920 {L'~', java_awt_event_KeyEvent_VK_DEAD_TILDE}, 2921 {0x02DC, java_awt_event_KeyEvent_VK_DEAD_TILDE}, 2922 {0x00AF, java_awt_event_KeyEvent_VK_DEAD_MACRON}, 2923 {0x02D8, java_awt_event_KeyEvent_VK_DEAD_BREVE}, 2924 {0x02D9, java_awt_event_KeyEvent_VK_DEAD_ABOVEDOT}, 2925 {L'"', java_awt_event_KeyEvent_VK_DEAD_DIAERESIS}, 2926 {0x00A8, java_awt_event_KeyEvent_VK_DEAD_DIAERESIS}, 2927 {0x02DA, java_awt_event_KeyEvent_VK_DEAD_ABOVERING}, 2928 {0x02DD, java_awt_event_KeyEvent_VK_DEAD_DOUBLEACUTE}, 2929 {0x02C7, java_awt_event_KeyEvent_VK_DEAD_CARON}, // aka hacek 2930 {L',', java_awt_event_KeyEvent_VK_DEAD_CEDILLA}, 2931 {0x00B8, java_awt_event_KeyEvent_VK_DEAD_CEDILLA}, 2932 {0x02DB, java_awt_event_KeyEvent_VK_DEAD_OGONEK}, 2933 {0x037A, java_awt_event_KeyEvent_VK_DEAD_IOTA}, // ASCII ??? 2934 {0x309B, java_awt_event_KeyEvent_VK_DEAD_VOICED_SOUND}, 2935 {0x309C, java_awt_event_KeyEvent_VK_DEAD_SEMIVOICED_SOUND}, 2936 {0,0} 2937 }; 2938 2939 // The full map of the current keyboard state including 2940 // windows virtual key, scancode, java virtual key, and unicode 2941 // for this key sans modifiers. 2942 // All but first element may be 0. 2943 // XXX in the update releases this is an addition to the unchanged existing code 2944 struct DynPrimaryKeymapEntry { 2945 UINT wkey; 2946 UINT scancode; 2947 UINT jkey; 2948 WCHAR unicode; 2949 }; 2950 2951 static DynPrimaryKeymapEntry dynPrimaryKeymap[256]; 2952 2953 void 2954 AwtComponent::InitDynamicKeyMapTable() 2955 { 2956 static BOOL kbdinited = FALSE; 2957 2958 if (!kbdinited) { 2959 AwtComponent::BuildDynamicKeyMapTable(); 2960 // We cannot build it here since JNI is not available yet: 2961 //AwtComponent::BuildPrimaryDynamicTable(); 2962 kbdinited = TRUE; 2963 } 2964 } 2965 2966 void 2967 AwtComponent::BuildDynamicKeyMapTable() 2968 { 2969 HKL hkl = GetKeyboardLayout(); 2970 2971 DTRACE_PRINTLN2("Building dynamic VK mapping tables: HKL = %08X (CP%d)", 2972 hkl, AwtComponent::GetCodePage()); 2973 2974 // Will need this to reset layout after dead keys. 2975 UINT spaceScanCode = ::MapVirtualKeyEx(VK_SPACE, 0, hkl); 2976 2977 // Entries in dynamic table that maps between Java VK and Windows 2978 // VK are built in three steps: 2979 // 1. Map windows VK to ANSI character (cannot map to unicode 2980 // directly, since ::ToUnicode is not implemented on win9x) 2981 // 2. Convert ANSI char to Unicode char 2982 // 3. Map Unicode char to Java VK via two auxilary tables. 2983 2984 for (DynamicKeyMapEntry *dynamic = dynamicKeyMapTable; 2985 dynamic->windowsKey != 0; 2986 ++dynamic) 2987 { 2988 // Defaults to VK_UNDEFINED 2989 dynamic->javaKey = java_awt_event_KeyEvent_VK_UNDEFINED; 2990 2991 BYTE kbdState[AwtToolkit::KB_STATE_SIZE]; 2992 AwtToolkit::GetKeyboardState(kbdState); 2993 2994 kbdState[dynamic->windowsKey] |= 0x80; // Press the key. 2995 2996 // Unpress modifiers, since they are most likely pressed as 2997 // part of the keyboard switching shortcut. 2998 kbdState[VK_CONTROL] &= ~0x80; 2999 kbdState[VK_SHIFT] &= ~0x80; 3000 kbdState[VK_MENU] &= ~0x80; 3001 3002 char cbuf[2] = { '\0', '\0'}; 3003 UINT scancode = ::MapVirtualKeyEx(dynamic->windowsKey, 0, hkl); 3004 int nchars = ::ToAsciiEx(dynamic->windowsKey, scancode, kbdState, 3005 (WORD*)cbuf, 0, hkl); 3006 3007 // Auxiliary table used to map Unicode character to Java VK. 3008 // Will assign a different table for dead keys (below). 3009 const CharToVKEntry *charMap = charToVKTable; 3010 3011 if (nchars < 0) { // Dead key 3012 // Use a different table for dead chars since different layouts 3013 // return different characters for the same dead key. 3014 charMap = charToDeadVKTable; 3015 3016 // We also need to reset layout so that next translation 3017 // is unaffected by the dead status. We do this by 3018 // translating <SPACE> key. 3019 kbdState[dynamic->windowsKey] &= ~0x80; 3020 kbdState[VK_SPACE] |= 0x80; 3021 3022 char junkbuf[2] = { '\0', '\0'}; 3023 ::ToAsciiEx(VK_SPACE, spaceScanCode, kbdState, 3024 (WORD*)junkbuf, 0, hkl); 3025 } 3026 3027 #ifdef DEBUG 3028 if (nchars == 0) { 3029 DTRACE_PRINTLN1("VK 0x%02X -> cannot convert to ANSI char", 3030 dynamic->windowsKey); 3031 continue; 3032 } 3033 else if (nchars > 1) { // can't happen, see reset code below 3034 DTRACE_PRINTLN3("VK 0x%02X -> converted to <0x%02X,0x%02X>", 3035 dynamic->windowsKey, 3036 (UCHAR)cbuf[0], (UCHAR)cbuf[1]); 3037 continue; 3038 } 3039 #endif 3040 3041 WCHAR ucbuf[2] = { L'\0', L'\0' }; 3042 int nconverted = ::MultiByteToWideChar(AwtComponent::GetCodePage(), 0, 3043 cbuf, 1, ucbuf, 2); 3044 #ifdef DEBUG 3045 if (nconverted < 0) { 3046 DTRACE_PRINTLN3("VK 0x%02X -> ANSI 0x%02X -> MultiByteToWideChar failed (0x%X)", 3047 dynamic->windowsKey, (UCHAR)cbuf[0], 3048 ::GetLastError()); 3049 continue; 3050 } 3051 #endif 3052 3053 WCHAR uc = ucbuf[0]; 3054 for (const CharToVKEntry *map = charMap; map->c != 0; ++map) { 3055 if (uc == map->c) { 3056 dynamic->javaKey = map->javaKey; 3057 break; 3058 } 3059 } 3060 3061 DTRACE_PRINTLN4("VK 0x%02X -> ANSI 0x%02X -> U+%04X -> Java VK 0x%X", 3062 dynamic->windowsKey, (UCHAR)cbuf[0], (UINT)ucbuf[0], 3063 dynamic->javaKey); 3064 } // for each VK_OEM_* 3065 } 3066 3067 3068 static BOOL isKanaLockAvailable() 3069 { 3070 // This method is to determine whether the Kana Lock feature is 3071 // available on the attached keyboard. Kana Lock feature does not 3072 // necessarily require that the real KANA keytop is available on 3073 // keyboard, so using MapVirtualKey(VK_KANA) is not sufficient for testing. 3074 // Instead of that we regard it as Japanese keyboard (w/ Kana Lock) if :- 3075 // 3076 // - the keyboard layout is Japanese (VK_KANA has the same value as VK_HANGUL) 3077 // - the keyboard is Japanese keyboard (keyboard type == 7). 3078 return (LOWORD(GetKeyboardLayout(0)) == MAKELANGID(LANG_JAPANESE, SUBLANG_DEFAULT)) 3079 && (GetKeyboardType(0) == 7); 3080 } 3081 3082 void AwtComponent::JavaKeyToWindowsKey(UINT javaKey, 3083 UINT *windowsKey, UINT *modifiers, UINT originalWindowsKey) 3084 { 3085 // Handle the few cases where a Java VK code corresponds to a Windows 3086 // key/modifier combination or applies only to specific keyboard layouts 3087 switch (javaKey) { 3088 case java_awt_event_KeyEvent_VK_ALL_CANDIDATES: 3089 *windowsKey = VK_CONVERT; 3090 *modifiers = java_awt_event_InputEvent_ALT_DOWN_MASK; 3091 return; 3092 case java_awt_event_KeyEvent_VK_PREVIOUS_CANDIDATE: 3093 *windowsKey = VK_CONVERT; 3094 *modifiers = java_awt_event_InputEvent_SHIFT_DOWN_MASK; 3095 return; 3096 case java_awt_event_KeyEvent_VK_CODE_INPUT: 3097 *windowsKey = VK_DBE_ALPHANUMERIC; 3098 *modifiers = java_awt_event_InputEvent_ALT_DOWN_MASK; 3099 return; 3100 case java_awt_event_KeyEvent_VK_KANA_LOCK: 3101 if (isKanaLockAvailable()) { 3102 *windowsKey = VK_KANA; 3103 *modifiers = java_awt_event_InputEvent_CTRL_DOWN_MASK; 3104 return; 3105 } 3106 } 3107 3108 // for the general case, use a bi-directional table 3109 for (int i = 0; keyMapTable[i].windowsKey != 0; i++) { 3110 if (keyMapTable[i].javaKey == javaKey) { 3111 *windowsKey = keyMapTable[i].windowsKey; 3112 *modifiers = 0; 3113 return; 3114 } 3115 } 3116 3117 // Bug 4766655 3118 // Two Windows keys could map to the same Java key, so 3119 // give preference to the originalWindowsKey if it is 3120 // specified (not IGNORE_KEY). 3121 if (originalWindowsKey == IGNORE_KEY) { 3122 for (int j = 0; dynamicKeyMapTable[j].windowsKey != 0; j++) { 3123 if (dynamicKeyMapTable[j].javaKey == javaKey) { 3124 *windowsKey = dynamicKeyMapTable[j].windowsKey; 3125 *modifiers = 0; 3126 return; 3127 } 3128 } 3129 } else { 3130 BOOL found = false; 3131 for (int j = 0; dynamicKeyMapTable[j].windowsKey != 0; j++) { 3132 if (dynamicKeyMapTable[j].javaKey == javaKey) { 3133 *windowsKey = dynamicKeyMapTable[j].windowsKey; 3134 *modifiers = 0; 3135 found = true; 3136 if (*windowsKey == originalWindowsKey) { 3137 return; /* if ideal case found return, else keep looking */ 3138 } 3139 } 3140 } 3141 if (found) { 3142 return; 3143 } 3144 } 3145 3146 *windowsKey = 0; 3147 *modifiers = 0; 3148 return; 3149 } 3150 3151 UINT AwtComponent::WindowsKeyToJavaKey(UINT windowsKey, UINT modifiers, UINT character, BOOL isDeadKey) 3152 3153 { 3154 // Handle the few cases where we need to take the modifier into 3155 // consideration for the Java VK code or where we have to take the keyboard 3156 // layout into consideration so that function keys can get 3157 // recognized in a platform-independent way. 3158 switch (windowsKey) { 3159 case VK_CONVERT: 3160 if ((modifiers & java_awt_event_InputEvent_ALT_DOWN_MASK) != 0) { 3161 return java_awt_event_KeyEvent_VK_ALL_CANDIDATES; 3162 } 3163 if ((modifiers & java_awt_event_InputEvent_SHIFT_DOWN_MASK) != 0) { 3164 return java_awt_event_KeyEvent_VK_PREVIOUS_CANDIDATE; 3165 } 3166 break; 3167 case VK_DBE_ALPHANUMERIC: 3168 if ((modifiers & java_awt_event_InputEvent_ALT_DOWN_MASK) != 0) { 3169 return java_awt_event_KeyEvent_VK_CODE_INPUT; 3170 } 3171 break; 3172 case VK_KANA: 3173 if (isKanaLockAvailable()) { 3174 return java_awt_event_KeyEvent_VK_KANA_LOCK; 3175 } 3176 break; 3177 }; 3178 3179 // check dead key 3180 if (isDeadKey) { 3181 for (int i = 0; charToDeadVKTable[i].c != 0; i++) { 3182 if (charToDeadVKTable[i].c == character) { 3183 return charToDeadVKTable[i].javaKey; 3184 } 3185 } 3186 } 3187 3188 // for the general case, use a bi-directional table 3189 for (int i = 0; keyMapTable[i].windowsKey != 0; i++) { 3190 if (keyMapTable[i].windowsKey == windowsKey) { 3191 return keyMapTable[i].javaKey; 3192 } 3193 } 3194 3195 for (int j = 0; dynamicKeyMapTable[j].windowsKey != 0; j++) { 3196 if (dynamicKeyMapTable[j].windowsKey == windowsKey) { 3197 if (dynamicKeyMapTable[j].javaKey != java_awt_event_KeyEvent_VK_UNDEFINED) { 3198 return dynamicKeyMapTable[j].javaKey; 3199 }else{ 3200 break; 3201 } 3202 } 3203 } 3204 3205 return java_awt_event_KeyEvent_VK_UNDEFINED; 3206 } 3207 3208 BOOL AwtComponent::IsNavigationKey(UINT wkey) { 3209 switch (wkey) { 3210 case VK_END: 3211 case VK_PRIOR: // PageUp 3212 case VK_NEXT: // PageDown 3213 case VK_HOME: 3214 case VK_LEFT: 3215 case VK_UP: 3216 case VK_RIGHT: 3217 case VK_DOWN: 3218 return TRUE; 3219 } 3220 return FALSE; 3221 } 3222 3223 // determine if a key is a numpad key (distinguishes the numpad 3224 // arrow keys from the non-numpad arrow keys, for example). 3225 BOOL AwtComponent::IsNumPadKey(UINT vkey, BOOL extended) 3226 { 3227 // Note: scancodes are the same for the numpad arrow keys and 3228 // the non-numpad arrow keys (also for PageUp, etc.). 3229 // The scancodes for the numpad divide and the non-numpad slash 3230 // are the same, but the wparams are different 3231 3232 DTRACE_PRINTLN3("AwtComponent::IsNumPadKey vkey = %d = 0x%x extended = %d", 3233 vkey, vkey, extended); 3234 3235 switch (vkey) { 3236 case VK_CLEAR: // numpad 5 with numlock off 3237 case VK_NUMPAD0: 3238 case VK_NUMPAD1: 3239 case VK_NUMPAD2: 3240 case VK_NUMPAD3: 3241 case VK_NUMPAD4: 3242 case VK_NUMPAD5: 3243 case VK_NUMPAD6: 3244 case VK_NUMPAD7: 3245 case VK_NUMPAD8: 3246 case VK_NUMPAD9: 3247 case VK_MULTIPLY: 3248 case VK_ADD: 3249 case VK_SEPARATOR: // numpad , not on US kbds 3250 case VK_SUBTRACT: 3251 case VK_DECIMAL: 3252 case VK_DIVIDE: 3253 case VK_NUMLOCK: 3254 return TRUE; 3255 break; 3256 case VK_END: 3257 case VK_PRIOR: // PageUp 3258 case VK_NEXT: // PageDown 3259 case VK_HOME: 3260 case VK_LEFT: 3261 case VK_UP: 3262 case VK_RIGHT: 3263 case VK_DOWN: 3264 case VK_INSERT: 3265 case VK_DELETE: 3266 // extended if non-numpad 3267 return (!extended); 3268 break; 3269 case VK_RETURN: // extended if on numpad 3270 return (extended); 3271 break; 3272 default: 3273 break; 3274 } 3275 3276 return FALSE; 3277 } 3278 static void 3279 resetKbdState( BYTE kstate[256]) { 3280 BYTE tmpState[256]; 3281 WCHAR wc[2]; 3282 memmove(tmpState, kstate, sizeof(kstate)); 3283 tmpState[VK_SHIFT] = 0; 3284 tmpState[VK_CONTROL] = 0; 3285 tmpState[VK_MENU] = 0; 3286 3287 ::ToUnicodeEx(VK_SPACE,::MapVirtualKey(VK_SPACE, 0), tmpState, wc, 2, 0, GetKeyboardLayout(0)); 3288 } 3289 3290 // XXX in the update releases this is an addition to the unchanged existing code 3291 // After the call, a table will have a unicode associated with a windows virtual keycode 3292 // sans modifiers. With some further simplification, one can 3293 // derive java keycode from it, and anyway we will pass this unicode value 3294 // all the way up in a comment to a KeyEvent. 3295 void 3296 AwtComponent::BuildPrimaryDynamicTable() { 3297 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); 3298 // XXX: how about that? 3299 //CriticalSection::Lock l(GetLock()); 3300 //if (GetPeer(env) == NULL) { 3301 // /* event received during termination. */ 3302 // return; 3303 //} 3304 3305 HKL hkl = GetKeyboardLayout(); 3306 UINT sc = 0; 3307 BYTE kbdState[AwtToolkit::KB_STATE_SIZE]; 3308 memset(kbdState, 0, sizeof (kbdState)); 3309 3310 // Use JNI call to obtain java key code. We should keep a list 3311 // of currently available keycodes in a single place. 3312 static jclass extKeyCodesCls; 3313 if( extKeyCodesCls == NULL) { 3314 jclass extKeyCodesClsLocal = env->FindClass("sun/awt/ExtendedKeyCodes"); 3315 DASSERT(extKeyCodesClsLocal); 3316 if (extKeyCodesClsLocal == NULL) { 3317 /* exception already thrown */ 3318 return; 3319 } 3320 extKeyCodesCls = (jclass)env->NewGlobalRef(extKeyCodesClsLocal); 3321 env->DeleteLocalRef(extKeyCodesClsLocal); 3322 } 3323 static jmethodID getExtendedKeyCodeForChar; 3324 if (getExtendedKeyCodeForChar == NULL) { 3325 getExtendedKeyCodeForChar = 3326 env->GetStaticMethodID(extKeyCodesCls, "getExtendedKeyCodeForChar", "(I)I"); 3327 DASSERT(getExtendedKeyCodeForChar); 3328 } 3329 jint extJKC; //extended Java key code 3330 3331 for (UINT i = 0; i < 256; i++) { 3332 dynPrimaryKeymap[i].wkey = i; 3333 dynPrimaryKeymap[i].jkey = java_awt_event_KeyEvent_VK_UNDEFINED; 3334 dynPrimaryKeymap[i].unicode = 0; 3335 3336 if ((sc = MapVirtualKey (i, 0)) == 0) { 3337 dynPrimaryKeymap[i].scancode = 0; 3338 continue; 3339 } 3340 dynPrimaryKeymap[i].scancode = sc; 3341 3342 // XXX process cases like VK_SHIFT etc. 3343 kbdState[i] = 0x80; // "key pressed". 3344 WCHAR wc[16]; 3345 int k = ::ToUnicodeEx(i, sc, kbdState, wc, 16, 0, hkl); 3346 if (k == 1) { 3347 // unicode 3348 dynPrimaryKeymap[i].unicode = wc[0]; 3349 if (dynPrimaryKeymap[i].jkey == java_awt_event_KeyEvent_VK_UNDEFINED) { 3350 // Convert unicode to java keycode. 3351 //dynPrimaryKeymap[i].jkey = ((UINT)(wc[0]) + 0x01000000); 3352 // 3353 //XXX If this key in on the keypad, we should force a special value equal to 3354 //XXX an old java keycode: but how to say if it is a keypad key? 3355 //XXX We'll do it in WmKeyUp/Down. 3356 extJKC = env->CallStaticIntMethod(extKeyCodesCls, 3357 getExtendedKeyCodeForChar, (jint)(wc[0])); 3358 dynPrimaryKeymap[i].jkey = extJKC; 3359 } 3360 }else if (k == -1) { 3361 // dead key: use charToDeadVKTable 3362 dynPrimaryKeymap[i].unicode = wc[0]; 3363 resetKbdState( kbdState ); 3364 for (const CharToVKEntry *map = charToDeadVKTable; map->c != 0; ++map) { 3365 if (wc[0] == map->c) { 3366 dynPrimaryKeymap[i].jkey = map->javaKey; 3367 break; 3368 } 3369 } 3370 } else if (k == 0) { 3371 // reset 3372 resetKbdState( kbdState ); 3373 }else { 3374 // k > 1: this key does generate multiple characters. Ignore it. 3375 // An example: Arabic Lam and Alef ligature. 3376 // There will be no extended keycode and thus shortcuts for this key. 3377 // XXX shouldn't we reset the kbd state? 3378 #ifdef DEBUG 3379 DTRACE_PRINTLN2("wkey 0x%02X (%d)", i,i); 3380 #endif 3381 } 3382 kbdState[i] = 0; // "key unpressed" 3383 } 3384 } 3385 void 3386 AwtComponent::UpdateDynPrimaryKeymap(UINT wkey, UINT jkeyLegacy, jint keyLocation, UINT modifiers) 3387 { 3388 if( wkey && wkey < 256 ) { 3389 if(keyLocation == java_awt_event_KeyEvent_KEY_LOCATION_NUMPAD) { 3390 // At the creation time, 3391 // dynPrimaryKeymap cannot distinguish between e.g. "/" and "NumPad /" 3392 dynPrimaryKeymap[wkey].jkey = jkeyLegacy; 3393 } 3394 if(dynPrimaryKeymap[wkey].jkey == java_awt_event_KeyEvent_VK_UNDEFINED) { 3395 // E.g. it is non-unicode key 3396 dynPrimaryKeymap[wkey].jkey = jkeyLegacy; 3397 } 3398 } 3399 } 3400 3401 UINT AwtComponent::WindowsKeyToJavaChar(UINT wkey, UINT modifiers, TransOps ops, BOOL &isDeadKey) 3402 { 3403 static Hashtable transTable("VKEY translations"); 3404 static Hashtable deadKeyFlagTable("Dead Key Flags"); 3405 isDeadKey = FALSE; 3406 3407 // Try to translate using last saved translation 3408 if (ops == LOAD) { 3409 void* deadKeyFlag = deadKeyFlagTable.remove(reinterpret_cast<void*>(static_cast<INT_PTR>(wkey))); 3410 void* value = transTable.remove(reinterpret_cast<void*>(static_cast<INT_PTR>(wkey))); 3411 if (value != NULL) { 3412 isDeadKey = static_cast<BOOL>(reinterpret_cast<INT_PTR>(deadKeyFlag)); 3413 return static_cast<UINT>(reinterpret_cast<INT_PTR>(value)); 3414 } 3415 } 3416 3417 // If the windows key is a return, wkey will equal 13 ('\r') 3418 // In this case, we want to return 10 ('\n') 3419 // Since ToAscii would convert VK_RETURN to '\r', we need 3420 // to have a special case here. 3421 if (wkey == VK_RETURN) 3422 return '\n'; 3423 3424 // high order bit in keyboardState indicates whether the key is down 3425 static const BYTE KEY_STATE_DOWN = 0x80; 3426 BYTE keyboardState[AwtToolkit::KB_STATE_SIZE]; 3427 AwtToolkit::GetKeyboardState(keyboardState); 3428 3429 // apply modifiers to keyboard state if necessary 3430 if (modifiers) { 3431 BOOL shiftIsDown = modifiers & java_awt_event_InputEvent_SHIFT_DOWN_MASK; 3432 BOOL altIsDown = modifiers & java_awt_event_InputEvent_ALT_DOWN_MASK; 3433 BOOL ctrlIsDown = modifiers & java_awt_event_InputEvent_CTRL_DOWN_MASK; 3434 3435 // Windows treats AltGr as Ctrl+Alt 3436 if (modifiers & java_awt_event_InputEvent_ALT_GRAPH_DOWN_MASK) { 3437 altIsDown = TRUE; 3438 ctrlIsDown = TRUE; 3439 } 3440 3441 if (shiftIsDown) { 3442 keyboardState[VK_SHIFT] |= KEY_STATE_DOWN; 3443 } 3444 3445 // fix for 4623376,4737679,4501485,4740906,4708221 (4173679/4122715) 3446 // Here we try to resolve a conflict with ::ToAsciiEx's translating 3447 // ALT+number key combinations. kdm@sarc.spb.su 3448 // yan: Do it for navigation keys only, otherwise some AltGr deadkeys fail. 3449 if( IsNavigationKey(wkey) ) { 3450 keyboardState[VK_MENU] &= ~KEY_STATE_DOWN; 3451 } 3452 3453 if (ctrlIsDown) 3454 { 3455 if (altIsDown) { 3456 // bugid 4215009: don't mess with AltGr == Ctrl + Alt 3457 keyboardState[VK_CONTROL] |= KEY_STATE_DOWN; 3458 } 3459 else { 3460 // bugid 4098210: old event model doesn't have KEY_TYPED 3461 // events, so try to provide a meaningful character for 3462 // Ctrl+<key>. Take Ctrl into account only when we know 3463 // that Ctrl+<key> will be an ASCII control. Ignore by 3464 // default. 3465 keyboardState[VK_CONTROL] &= ~KEY_STATE_DOWN; 3466 3467 // Letters have Ctrl+<letter> counterparts. According to 3468 // <winuser.h> VK_A through VK_Z are the same as ASCII 3469 // 'A' through 'Z'. 3470 if (wkey >= 'A' && wkey <= 'Z') { 3471 keyboardState[VK_CONTROL] |= KEY_STATE_DOWN; 3472 } 3473 else { 3474 // Non-letter controls 033 to 037 are: 3475 // ^[ (ESC), ^\ (FS), ^] (GS), ^^ (RS), and ^_ (US) 3476 3477 // Shift state bits returned by ::VkKeyScan in HIBYTE 3478 static const UINT _VKS_SHIFT_MASK = 0x01; 3479 static const UINT _VKS_CTRL_MASK = 0x02; 3480 static const UINT _VKS_ALT_MASK = 0x04; 3481 3482 // Check to see whether there is a meaningful translation 3483 TCHAR ch; 3484 short vk; 3485 for (ch = _T('\033'); ch < _T('\040'); ch++) { 3486 vk = ::VkKeyScan(ch); 3487 if (wkey == LOBYTE(vk)) { 3488 UINT shiftState = HIBYTE(vk); 3489 if ((shiftState & _VKS_CTRL_MASK) || 3490 (!(shiftState & _VKS_SHIFT_MASK) 3491 == !shiftIsDown)) 3492 { 3493 keyboardState[VK_CONTROL] |= KEY_STATE_DOWN; 3494 } 3495 break; 3496 } 3497 } 3498 } 3499 } // ctrlIsDown && altIsDown 3500 } // ctrlIsDown 3501 } // modifiers 3502 3503 // instead of creating our own conversion tables, I'll let Win32 3504 // convert the character for me. 3505 WORD wChar[2]; 3506 UINT scancode = ::MapVirtualKey(wkey, 0); 3507 int converted = ::ToUnicodeEx(wkey, scancode, keyboardState, 3508 wChar, 2, 0, GetKeyboardLayout()); 3509 3510 UINT translation; 3511 BOOL deadKeyFlag = (converted == 2); 3512 3513 // Dead Key 3514 if (converted < 0) { 3515 translation = java_awt_event_KeyEvent_CHAR_UNDEFINED; 3516 } else 3517 // No translation available -- try known conversions or else punt. 3518 if (converted == 0) { 3519 if (wkey == VK_DELETE) { 3520 translation = '\177'; 3521 } else 3522 if (wkey >= VK_NUMPAD0 && wkey <= VK_NUMPAD9) { 3523 translation = '0' + wkey - VK_NUMPAD0; 3524 } else { 3525 translation = java_awt_event_KeyEvent_CHAR_UNDEFINED; 3526 } 3527 } else 3528 // the caller expects a Unicode character. 3529 if (converted > 0) { 3530 translation = wChar[0]; 3531 } 3532 if (ops == SAVE) { 3533 transTable.put(reinterpret_cast<void*>(static_cast<INT_PTR>(wkey)), 3534 reinterpret_cast<void*>(static_cast<INT_PTR>(translation))); 3535 if (deadKeyFlag) { 3536 deadKeyFlagTable.put(reinterpret_cast<void*>(static_cast<INT_PTR>(wkey)), 3537 reinterpret_cast<void*>(static_cast<INT_PTR>(deadKeyFlag))); 3538 } else { 3539 deadKeyFlagTable.remove(reinterpret_cast<void*>(static_cast<INT_PTR>(wkey))); 3540 } 3541 } 3542 3543 isDeadKey = deadKeyFlag; 3544 return translation; 3545 } 3546 3547 MsgRouting AwtComponent::WmKeyDown(UINT wkey, UINT repCnt, 3548 UINT flags, BOOL system) 3549 { 3550 // VK_PROCESSKEY is a special value which means 3551 // "Current IME wants to consume this KeyEvent" 3552 // Real key code is saved by IMM32.DLL and can be retrieved by 3553 // calling ImmGetVirtualKey(); 3554 if (wkey == VK_PROCESSKEY) { 3555 return mrDoDefault; 3556 } 3557 MSG msg; 3558 InitMessage(&msg, (system ? WM_SYSKEYDOWN : WM_KEYDOWN), 3559 wkey, MAKELPARAM(repCnt, flags)); 3560 3561 UINT modifiers = GetJavaModifiers(); 3562 jint keyLocation = GetKeyLocation(wkey, flags); 3563 BOOL isDeadKey = FALSE; 3564 UINT character = WindowsKeyToJavaChar(wkey, modifiers, SAVE, isDeadKey); 3565 UINT jkey = WindowsKeyToJavaKey(wkey, modifiers, character, isDeadKey); 3566 UpdateDynPrimaryKeymap(wkey, jkey, keyLocation, modifiers); 3567 3568 3569 SendKeyEventToFocusOwner(java_awt_event_KeyEvent_KEY_PRESSED, 3570 TimeHelper::windowsToUTC(msg.time), jkey, character, 3571 modifiers, keyLocation, (jlong)wkey, &msg); 3572 3573 // bugid 4724007: Windows does not create a WM_CHAR for the Del key 3574 // for some reason, so we need to create the KEY_TYPED event on the 3575 // WM_KEYDOWN. Use null msg so the character doesn't get sent back 3576 // to the native window for processing (this event is synthesized 3577 // for Java - we don't want Windows trying to process it). 3578 if (jkey == java_awt_event_KeyEvent_VK_DELETE) { 3579 SendKeyEventToFocusOwner(java_awt_event_KeyEvent_KEY_TYPED, 3580 TimeHelper::windowsToUTC(msg.time), 3581 java_awt_event_KeyEvent_VK_UNDEFINED, 3582 character, modifiers, 3583 java_awt_event_KeyEvent_KEY_LOCATION_UNKNOWN, (jlong)0); 3584 } 3585 3586 return mrConsume; 3587 } 3588 3589 MsgRouting AwtComponent::WmKeyUp(UINT wkey, UINT repCnt, 3590 UINT flags, BOOL system) 3591 { 3592 3593 // VK_PROCESSKEY is a special value which means 3594 // "Current IME wants to consume this KeyEvent" 3595 // Real key code is saved by IMM32.DLL and can be retrieved by 3596 // calling ImmGetVirtualKey(); 3597 if (wkey == VK_PROCESSKEY) { 3598 return mrDoDefault; 3599 } 3600 MSG msg; 3601 InitMessage(&msg, (system ? WM_SYSKEYUP : WM_KEYUP), 3602 wkey, MAKELPARAM(repCnt, flags)); 3603 3604 UINT modifiers = GetJavaModifiers(); 3605 jint keyLocation = GetKeyLocation(wkey, flags); 3606 BOOL isDeadKey = FALSE; 3607 UINT character = WindowsKeyToJavaChar(wkey, modifiers, LOAD, isDeadKey); 3608 UINT jkey = WindowsKeyToJavaKey(wkey, modifiers, character, isDeadKey); 3609 UpdateDynPrimaryKeymap(wkey, jkey, keyLocation, modifiers); 3610 3611 SendKeyEventToFocusOwner(java_awt_event_KeyEvent_KEY_RELEASED, 3612 TimeHelper::windowsToUTC(msg.time), jkey, character, 3613 modifiers, keyLocation, (jlong)wkey, &msg); 3614 return mrConsume; 3615 } 3616 3617 MsgRouting AwtComponent::WmInputLangChange(UINT charset, HKL hKeyboardLayout) 3618 { 3619 // Normally we would be able to use charset and TranslateCharSetInfo 3620 // to get a code page that should be associated with this keyboard 3621 // layout change. However, there seems to be an NT 4.0 bug associated 3622 // with the WM_INPUTLANGCHANGE message, which makes the charset parameter 3623 // unreliable, especially on Asian systems. Our workaround uses the 3624 // keyboard layout handle instead. 3625 m_hkl = hKeyboardLayout; 3626 m_idLang = LOWORD(hKeyboardLayout); // lower word of HKL is LANGID 3627 m_CodePage = LangToCodePage(m_idLang); 3628 BuildDynamicKeyMapTable(); // compute new mappings for VK_OEM 3629 BuildPrimaryDynamicTable(); 3630 return mrConsume; // do not propagate to children 3631 } 3632 3633 // Convert Language ID to CodePage 3634 UINT AwtComponent::LangToCodePage(LANGID idLang) 3635 { 3636 TCHAR strCodePage[MAX_ACP_STR_LEN]; 3637 // use the LANGID to create a LCID 3638 LCID idLocale = MAKELCID(idLang, SORT_DEFAULT); 3639 // get the ANSI code page associated with this locale 3640 if (GetLocaleInfo(idLocale, LOCALE_IDEFAULTANSICODEPAGE, strCodePage, sizeof(strCodePage)/sizeof(TCHAR)) > 0 ) 3641 return _ttoi(strCodePage); 3642 else 3643 return GetACP(); 3644 } 3645 3646 3647 MsgRouting AwtComponent::WmIMEChar(UINT character, UINT repCnt, UINT flags, BOOL system) 3648 { 3649 // We will simply create Java events here. 3650 WCHAR unicodeChar = character; 3651 MSG msg; 3652 InitMessage(&msg, WM_IME_CHAR, character, 3653 MAKELPARAM(repCnt, flags)); 3654 3655 jint modifiers = GetJavaModifiers(); 3656 SendKeyEventToFocusOwner(java_awt_event_KeyEvent_KEY_TYPED, 3657 TimeHelper::windowsToUTC(msg.time), 3658 java_awt_event_KeyEvent_VK_UNDEFINED, 3659 unicodeChar, modifiers, 3660 java_awt_event_KeyEvent_KEY_LOCATION_UNKNOWN, (jlong)0, 3661 &msg); 3662 return mrConsume; 3663 } 3664 3665 MsgRouting AwtComponent::WmChar(UINT character, UINT repCnt, UINT flags, 3666 BOOL system) 3667 { 3668 // Will only get WmChar messages with DBCS if we create them for 3669 // an Edit class in the WmForwardChar method. These synthesized 3670 // DBCS chars are ok to pass on directly to the default window 3671 // procedure. They've already been filtered through the Java key 3672 // event queue. We will never get the trail byte since the edit 3673 // class will PeekMessage(&msg, hwnd, WM_CHAR, WM_CHAR, 3674 // PM_REMOVE). I would like to be able to pass this character off 3675 // via WM_AWT_FORWARD_BYTE, but the Edit classes don't seem to 3676 // like that. 3677 3678 // We will simply create Java events here. 3679 UINT message = system ? WM_SYSCHAR : WM_CHAR; 3680 3681 // The Alt modifier is reported in the 29th bit of the lParam, 3682 // i.e., it is the 13th bit of `flags' (which is HIWORD(lParam)). 3683 bool alt_is_down = (flags & (1<<13)) != 0; 3684 3685 // Fix for bug 4141621, corrected by fix for bug 6223726: Alt+space doesn't invoke system menu 3686 // We should not pass this particular combination to Java. 3687 3688 if (system && alt_is_down) { 3689 if (character == VK_SPACE) { 3690 return mrDoDefault; 3691 } 3692 } 3693 3694 // If this is a WM_CHAR (non-system) message, then the Alt flag 3695 // indicates that the character was typed using an AltGr key 3696 // (which Windows treats as Ctrl+Alt), so in this case we do NOT 3697 // pass the Ctrl and Alt modifiers to Java, but instead we 3698 // replace them with Java's AltGraph modifier. Note: the AltGraph 3699 // modifier does not exist in 1.1.x releases. 3700 jint modifiers = GetJavaModifiers(); 3701 if (!system && alt_is_down) { 3702 // character typed with AltGraph 3703 modifiers &= ~(java_awt_event_InputEvent_ALT_DOWN_MASK 3704 | java_awt_event_InputEvent_CTRL_DOWN_MASK); 3705 modifiers |= java_awt_event_InputEvent_ALT_GRAPH_DOWN_MASK; 3706 } 3707 3708 WCHAR unicodeChar = character; 3709 3710 // Kludge: Combine pending single byte with this char for some Chinese IMEs 3711 if (m_PendingLeadByte != 0) { 3712 character = (m_PendingLeadByte & 0x00ff) | (character << 8); 3713 m_PendingLeadByte = 0; 3714 ::MultiByteToWideChar(GetCodePage(), 0, (CHAR*)&character, 2, 3715 &unicodeChar, 1); 3716 } 3717 3718 if (unicodeChar == VK_RETURN) { 3719 // Enter key generates \r in windows, but \n is required in java 3720 unicodeChar = java_awt_event_KeyEvent_VK_ENTER; 3721 } 3722 MSG msg; 3723 InitMessage(&msg, message, character, 3724 MAKELPARAM(repCnt, flags)); 3725 SendKeyEventToFocusOwner(java_awt_event_KeyEvent_KEY_TYPED, 3726 TimeHelper::windowsToUTC(msg.time), 3727 java_awt_event_KeyEvent_VK_UNDEFINED, 3728 unicodeChar, modifiers, 3729 java_awt_event_KeyEvent_KEY_LOCATION_UNKNOWN, (jlong)0, 3730 &msg); 3731 return mrConsume; 3732 } 3733 3734 MsgRouting AwtComponent::WmForwardChar(WCHAR character, LPARAM lParam, 3735 BOOL synthetic) 3736 { 3737 // just post WM_CHAR with unicode key value 3738 DefWindowProc(WM_CHAR, (WPARAM)character, lParam); 3739 return mrConsume; 3740 } 3741 3742 MsgRouting AwtComponent::WmPaste() 3743 { 3744 return mrDoDefault; 3745 } 3746 3747 // support IME Composition messages 3748 void AwtComponent::SetCompositionWindow(RECT& r) 3749 { 3750 HWND hwnd = ImmGetHWnd(); 3751 HIMC hIMC = ImmGetContext(hwnd); 3752 if (hIMC == NULL) { 3753 return; 3754 } 3755 COMPOSITIONFORM cf = {CFS_DEFAULT, {0, 0}, {0, 0, 0, 0}}; 3756 ImmSetCompositionWindow(hIMC, &cf); 3757 ImmReleaseContext(hwnd, hIMC); 3758 } 3759 3760 void AwtComponent::OpenCandidateWindow(int x, int y) 3761 { 3762 UINT bits = 1; 3763 RECT rc; 3764 GetWindowRect(GetHWnd(), &rc); 3765 3766 for (int iCandType=0; iCandType<32; iCandType++, bits<<=1) { 3767 if ( m_bitsCandType & bits ) 3768 SetCandidateWindow(iCandType, x-rc.left, y-rc.top); 3769 } 3770 if (m_bitsCandType != 0) { 3771 // REMIND: is there any chance GetProxyFocusOwner() returns NULL here? 3772 ::DefWindowProc(ImmGetHWnd(), 3773 WM_IME_NOTIFY, IMN_OPENCANDIDATE, m_bitsCandType); 3774 } 3775 } 3776 3777 void AwtComponent::SetCandidateWindow(int iCandType, int x, int y) 3778 { 3779 HWND hwnd = ImmGetHWnd(); 3780 HIMC hIMC = ImmGetContext(hwnd); 3781 CANDIDATEFORM cf; 3782 cf.dwIndex = iCandType; 3783 cf.dwStyle = CFS_CANDIDATEPOS; 3784 cf.ptCurrentPos.x = x; 3785 cf.ptCurrentPos.y = y; 3786 3787 ImmSetCandidateWindow(hIMC, &cf); 3788 ImmReleaseContext(hwnd, hIMC); 3789 } 3790 3791 MsgRouting AwtComponent::WmImeSetContext(BOOL fSet, LPARAM *lplParam) 3792 { 3793 // If the Windows input context is disabled, do not let Windows 3794 // display any UIs. 3795 HWND hwnd = ImmGetHWnd(); 3796 HIMC hIMC = ImmGetContext(hwnd); 3797 if (hIMC == NULL) { 3798 *lplParam = 0; 3799 return mrDoDefault; 3800 } 3801 ImmReleaseContext(hwnd, hIMC); 3802 3803 if (fSet) { 3804 LPARAM lParam = *lplParam; 3805 if (!m_useNativeCompWindow) { 3806 // stop to draw native composing window. 3807 *lplParam &= ~ISC_SHOWUICOMPOSITIONWINDOW; 3808 } 3809 } 3810 return mrDoDefault; 3811 } 3812 3813 MsgRouting AwtComponent::WmImeNotify(WPARAM subMsg, LPARAM bitsCandType) 3814 { 3815 if (!m_useNativeCompWindow && subMsg == IMN_OPENCANDIDATE) { 3816 m_bitsCandType = bitsCandType; 3817 InquireCandidatePosition(); 3818 return mrConsume; 3819 } 3820 return mrDoDefault; 3821 } 3822 3823 MsgRouting AwtComponent::WmImeStartComposition() 3824 { 3825 if (m_useNativeCompWindow) { 3826 RECT rc; 3827 ::GetClientRect(GetHWnd(), &rc); 3828 SetCompositionWindow(rc); 3829 return mrDoDefault; 3830 } else 3831 return mrConsume; 3832 } 3833 3834 MsgRouting AwtComponent::WmImeEndComposition() 3835 { 3836 if (m_useNativeCompWindow) return mrDoDefault; 3837 3838 SendInputMethodEvent( 3839 java_awt_event_InputMethodEvent_INPUT_METHOD_TEXT_CHANGED, 3840 NULL, 0, NULL, NULL, 0, NULL, NULL, 0, 0, 0 ); 3841 return mrConsume; 3842 } 3843 3844 MsgRouting AwtComponent::WmImeComposition(WORD wChar, LPARAM flags) 3845 { 3846 if (m_useNativeCompWindow) return mrDoDefault; 3847 3848 int* bndClauseW = NULL; 3849 jstring* readingClauseW = NULL; 3850 int* bndAttrW = NULL; 3851 BYTE* valAttrW = NULL; 3852 int cClauseW = 0; 3853 AwtInputTextInfor* textInfor = NULL; 3854 3855 try { 3856 HWND hwnd = ImmGetHWnd(); 3857 HIMC hIMC = ImmGetContext(hwnd); 3858 DASSERT(hIMC!=0); 3859 3860 textInfor = new AwtInputTextInfor; 3861 textInfor->GetContextData(hIMC, flags); 3862 ImmReleaseContext(hwnd, hIMC); 3863 3864 jstring jtextString = textInfor->GetText(); 3865 /* The conditions to send the input method event to AWT EDT are: 3866 1. Whenever there is a composition message sent regarding whether 3867 the composition text is NULL or not. See details at bug 6222692. 3868 2. When there is a committed message sent, in which case, we have to 3869 check whether the committed string is NULL or not. If the committed string 3870 is NULL, there is no need to send any input method event. 3871 (Minor note: 'jtextString' returned is the merged string in the case of 3872 partial commit.) 3873 */ 3874 if ((flags & GCS_RESULTSTR && jtextString != NULL) || 3875 (flags & GCS_COMPSTR)) { 3876 int cursorPosW = textInfor->GetCursorPosition(); 3877 // In order not to delete the readingClauseW in the catch clause, 3878 // calling GetAttributeInfor before GetClauseInfor. 3879 int cAttrW = textInfor->GetAttributeInfor(bndAttrW, valAttrW); 3880 cClauseW = textInfor->GetClauseInfor(bndClauseW, readingClauseW); 3881 3882 /* Send INPUT_METHOD_TEXT_CHANGED event to the WInputMethod which in turn sends 3883 the event to AWT EDT. 3884 3885 The last two paremeters are set to equal since we don't have recommendations for 3886 the visible position within the current composed text. See details at 3887 java.awt.event.InputMethodEvent. 3888 */ 3889 SendInputMethodEvent(java_awt_event_InputMethodEvent_INPUT_METHOD_TEXT_CHANGED, 3890 jtextString, 3891 cClauseW, bndClauseW, readingClauseW, 3892 cAttrW, bndAttrW, valAttrW, 3893 textInfor->GetCommittedTextLength(), 3894 cursorPosW, cursorPosW); 3895 } 3896 } catch (...) { 3897 // since GetClauseInfor and GetAttributeInfor could throw exception, we have to release 3898 // the pointer here. 3899 delete [] bndClauseW; 3900 delete [] readingClauseW; 3901 delete [] bndAttrW; 3902 delete [] valAttrW; 3903 throw; 3904 } 3905 3906 /* Free the storage allocated. Since jtextString won't be passed from threads 3907 * to threads, we just use the local ref and it will be deleted within the destructor 3908 * of AwtInputTextInfor object. 3909 */ 3910 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); 3911 if (cClauseW && readingClauseW) { 3912 for (int i = 0; i < cClauseW; i ++) { 3913 if (readingClauseW[i]) { 3914 env->DeleteLocalRef(readingClauseW[i]); 3915 } 3916 } 3917 } 3918 delete [] bndClauseW; 3919 delete [] readingClauseW; 3920 delete [] bndAttrW; 3921 delete [] valAttrW; 3922 delete textInfor; 3923 3924 return mrConsume; 3925 } 3926 3927 // 3928 // generate and post InputMethodEvent 3929 // 3930 void AwtComponent::SendInputMethodEvent(jint id, jstring text, 3931 int cClause, int* rgClauseBoundary, jstring* rgClauseReading, 3932 int cAttrBlock, int* rgAttrBoundary, BYTE *rgAttrValue, 3933 int commitedTextLength, int caretPos, int visiblePos) 3934 { 3935 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); 3936 3937 // assumption for array type casting 3938 DASSERT(sizeof(int)==sizeof(jint)); 3939 DASSERT(sizeof(BYTE)==sizeof(jbyte)); 3940 3941 // caluse information 3942 jintArray clauseBoundary = NULL; 3943 jobjectArray clauseReading = NULL; 3944 if (cClause && rgClauseBoundary && rgClauseReading) { 3945 // convert clause boundary offset array to java array 3946 clauseBoundary = env->NewIntArray(cClause+1); 3947 env->SetIntArrayRegion(clauseBoundary, 0, cClause+1, (jint *)rgClauseBoundary); 3948 DASSERT(!safe_ExceptionOccurred(env)); 3949 3950 // convert clause reading string array to java array 3951 clauseReading = env->NewObjectArray(cClause, JNU_ClassString(env), NULL); 3952 for (int i=0; i<cClause; i++) env->SetObjectArrayElement(clauseReading, i, rgClauseReading[i]); 3953 DASSERT(!safe_ExceptionOccurred(env)); 3954 } 3955 3956 3957 // attrubute value definition in WInputMethod.java must be equal to that in IMM.H 3958 DASSERT(ATTR_INPUT==sun_awt_windows_WInputMethod_ATTR_INPUT); 3959 DASSERT(ATTR_TARGET_CONVERTED==sun_awt_windows_WInputMethod_ATTR_TARGET_CONVERTED); 3960 DASSERT(ATTR_CONVERTED==sun_awt_windows_WInputMethod_ATTR_CONVERTED); 3961 DASSERT(ATTR_TARGET_NOTCONVERTED==sun_awt_windows_WInputMethod_ATTR_TARGET_NOTCONVERTED); 3962 DASSERT(ATTR_INPUT_ERROR==sun_awt_windows_WInputMethod_ATTR_INPUT_ERROR); 3963 3964 // attribute information 3965 jintArray attrBoundary = NULL; 3966 jbyteArray attrValue = NULL; 3967 if (cAttrBlock && rgAttrBoundary && rgAttrValue) { 3968 // convert attribute boundary offset array to java array 3969 attrBoundary = env->NewIntArray(cAttrBlock+1); 3970 env->SetIntArrayRegion(attrBoundary, 0, cAttrBlock+1, (jint *)rgAttrBoundary); 3971 DASSERT(!safe_ExceptionOccurred(env)); 3972 3973 // convert attribute value byte array to java array 3974 attrValue = env->NewByteArray(cAttrBlock); 3975 env->SetByteArrayRegion(attrValue, 0, cAttrBlock, (jbyte *)rgAttrValue); 3976 DASSERT(!safe_ExceptionOccurred(env)); 3977 } 3978 3979 3980 // get global reference of WInputMethod class (run only once) 3981 static jclass wInputMethodCls = NULL; 3982 if (wInputMethodCls == NULL) { 3983 jclass wInputMethodClsLocal = env->FindClass("sun/awt/windows/WInputMethod"); 3984 DASSERT(wInputMethodClsLocal); 3985 if (wInputMethodClsLocal == NULL) { 3986 /* exception already thrown */ 3987 return; 3988 } 3989 wInputMethodCls = (jclass)env->NewGlobalRef(wInputMethodClsLocal); 3990 env->DeleteLocalRef(wInputMethodClsLocal); 3991 } 3992 3993 // get method ID of sendInputMethodEvent() (run only once) 3994 static jmethodID sendIMEventMid = 0; 3995 if (sendIMEventMid == 0) { 3996 sendIMEventMid = env->GetMethodID(wInputMethodCls, "sendInputMethodEvent", 3997 "(IJLjava/lang/String;[I[Ljava/lang/String;[I[BIII)V"); 3998 DASSERT(sendIMEventMid); 3999 } 4000 4001 // call m_InputMethod.sendInputMethod() 4002 env->CallVoidMethod(m_InputMethod, sendIMEventMid, id, TimeHelper::getMessageTimeUTC(), 4003 text, clauseBoundary, clauseReading, attrBoundary, 4004 attrValue, commitedTextLength, caretPos, visiblePos); 4005 if (safe_ExceptionOccurred(env)) env->ExceptionDescribe(); 4006 DASSERT(!safe_ExceptionOccurred(env)); 4007 4008 } 4009 4010 4011 4012 // 4013 // Inquires candidate position according to the composed text 4014 // 4015 void AwtComponent::InquireCandidatePosition() 4016 { 4017 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); 4018 4019 // get global reference of WInputMethod class (run only once) 4020 static jclass wInputMethodCls = NULL; 4021 if (wInputMethodCls == NULL) { 4022 jclass wInputMethodClsLocal = env->FindClass("sun/awt/windows/WInputMethod"); 4023 DASSERT(wInputMethodClsLocal); 4024 if (wInputMethodClsLocal == NULL) { 4025 /* exception already thrown */ 4026 return; 4027 } 4028 wInputMethodCls = (jclass)env->NewGlobalRef(wInputMethodClsLocal); 4029 env->DeleteLocalRef(wInputMethodClsLocal); 4030 } 4031 4032 // get method ID of sendInputMethodEvent() (run only once) 4033 static jmethodID inqCandPosMid = 0; 4034 if (inqCandPosMid == 0) { 4035 inqCandPosMid = env->GetMethodID(wInputMethodCls, "inquireCandidatePosition", 4036 "()V"); 4037 DASSERT(!safe_ExceptionOccurred(env)); 4038 DASSERT(inqCandPosMid); 4039 } 4040 4041 // call m_InputMethod.sendInputMethod() 4042 jobject candPos = env->CallObjectMethod(m_InputMethod, inqCandPosMid); 4043 DASSERT(!safe_ExceptionOccurred(env)); 4044 } 4045 4046 HWND AwtComponent::ImmGetHWnd() 4047 { 4048 HWND proxy = GetProxyFocusOwner(); 4049 return (proxy != NULL) ? proxy : GetHWnd(); 4050 } 4051 4052 HIMC AwtComponent::ImmAssociateContext(HIMC himc) 4053 { 4054 return ::ImmAssociateContext(ImmGetHWnd(), himc); 4055 } 4056 4057 HWND AwtComponent::GetProxyFocusOwner() 4058 { 4059 AwtWindow *window = GetContainer(); 4060 if (window != 0) { 4061 AwtFrame *owner = window->GetOwningFrameOrDialog(); 4062 if (owner != 0) { 4063 return owner->GetProxyFocusOwner(); 4064 } else if (!window->IsSimpleWindow()) { // isn't an owned simple window 4065 return ((AwtFrame*)window)->GetProxyFocusOwner(); 4066 } 4067 } 4068 return (HWND)NULL; 4069 } 4070 4071 /* Call DefWindowProc for the focus proxy, if any */ 4072 void AwtComponent::CallProxyDefWindowProc(UINT message, WPARAM wParam, 4073 LPARAM lParam, LRESULT &retVal, MsgRouting &mr) 4074 { 4075 if (mr != mrConsume) { 4076 HWND proxy = GetProxyFocusOwner(); 4077 if (proxy != NULL) { 4078 retVal = ComCtl32Util::GetInstance().DefWindowProc(NULL, proxy, message, wParam, lParam); 4079 mr = mrConsume; 4080 } 4081 } 4082 } 4083 4084 MsgRouting AwtComponent::WmCommand(UINT id, HWND hWndChild, UINT notifyCode) 4085 { 4086 /* Menu/Accelerator */ 4087 if (hWndChild == 0) { 4088 AwtObject* obj = AwtToolkit::GetInstance().LookupCmdID(id); 4089 if (obj == NULL) { 4090 return mrConsume; 4091 } 4092 DASSERT(((AwtMenuItem*)obj)->GetID() == id); 4093 obj->DoCommand(); 4094 return mrConsume; 4095 } 4096 /* Child id notification */ 4097 else { 4098 AwtComponent* child = AwtComponent::GetComponent(hWndChild); 4099 if (child) { 4100 child->WmNotify(notifyCode); 4101 } 4102 } 4103 return mrDoDefault; 4104 } 4105 4106 MsgRouting AwtComponent::WmNotify(UINT notifyCode) 4107 { 4108 return mrDoDefault; 4109 } 4110 4111 MsgRouting AwtComponent::WmCompareItem(UINT ctrlId, 4112 COMPAREITEMSTRUCT &compareInfo, 4113 LRESULT &result) 4114 { 4115 AwtComponent* child = AwtComponent::GetComponent(compareInfo.hwndItem); 4116 if (child == this) { 4117 /* DoCallback("handleItemDelete", */ 4118 } 4119 else if (child) { 4120 return child->WmCompareItem(ctrlId, compareInfo, result); 4121 } 4122 return mrConsume; 4123 } 4124 4125 MsgRouting AwtComponent::WmDeleteItem(UINT ctrlId, 4126 DELETEITEMSTRUCT &deleteInfo) 4127 { 4128 /* 4129 * Workaround for NT 4.0 bug -- if SetWindowPos is called on a AwtList 4130 * window, a WM_DELETEITEM message is sent to its parent with a window 4131 * handle of one of the list's child windows. The property lookup 4132 * succeeds, but the HWNDs don't match. 4133 */ 4134 if (deleteInfo.hwndItem == NULL) { 4135 return mrConsume; 4136 } 4137 AwtComponent* child = (AwtComponent *)AwtComponent::GetComponent(deleteInfo.hwndItem); 4138 4139 if (child && child->GetHWnd() != deleteInfo.hwndItem) { 4140 return mrConsume; 4141 } 4142 4143 if (child == this) { 4144 /*DoCallback("handleItemDelete", */ 4145 } 4146 else if (child) { 4147 return child->WmDeleteItem(ctrlId, deleteInfo); 4148 } 4149 return mrConsume; 4150 } 4151 4152 MsgRouting AwtComponent::WmDrawItem(UINT ctrlId, DRAWITEMSTRUCT &drawInfo) 4153 { 4154 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); 4155 4156 if (drawInfo.CtlType == ODT_MENU) { 4157 if (drawInfo.itemData != 0) { 4158 AwtMenu* menu = (AwtMenu*)(drawInfo.itemData); 4159 menu->DrawItem(drawInfo); 4160 } 4161 } else { 4162 return OwnerDrawItem(ctrlId, drawInfo); 4163 } 4164 return mrConsume; 4165 } 4166 4167 MsgRouting AwtComponent::WmMeasureItem(UINT ctrlId, 4168 MEASUREITEMSTRUCT &measureInfo) 4169 { 4170 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); 4171 4172 if (measureInfo.CtlType == ODT_MENU) { 4173 if (measureInfo.itemData != 0) { 4174 AwtMenu* menu = (AwtMenu*)(measureInfo.itemData); 4175 HDC hDC = ::GetDC(GetHWnd()); 4176 /* menu->MeasureItem(env, hDC, measureInfo); */ 4177 menu->MeasureItem(hDC, measureInfo); 4178 ::ReleaseDC(GetHWnd(), hDC); 4179 } 4180 } else { 4181 return OwnerMeasureItem(ctrlId, measureInfo); 4182 } 4183 return mrConsume; 4184 } 4185 4186 MsgRouting AwtComponent::OwnerDrawItem(UINT ctrlId, 4187 DRAWITEMSTRUCT &drawInfo) 4188 { 4189 AwtComponent* child = AwtComponent::GetComponent(drawInfo.hwndItem); 4190 if (child == this) { 4191 /* DoCallback("handleItemDelete", */ 4192 } else if (child != NULL) { 4193 return child->WmDrawItem(ctrlId, drawInfo); 4194 } 4195 return mrConsume; 4196 } 4197 4198 MsgRouting AwtComponent::OwnerMeasureItem(UINT ctrlId, 4199 MEASUREITEMSTRUCT &measureInfo) 4200 { 4201 HWND hChild = ::GetDlgItem(GetHWnd(), measureInfo.CtlID); 4202 AwtComponent* child = AwtComponent::GetComponent(hChild); 4203 /* 4204 * If the parent cannot find the child's instance from its handle, 4205 * maybe the child is in its creation. So the child must be searched 4206 * from the list linked before the child's creation. 4207 */ 4208 if (child == NULL) { 4209 child = SearchChild((UINT)ctrlId); 4210 } 4211 4212 if (child == this) { 4213 /* DoCallback("handleItemDelete", */ 4214 } 4215 else if (child) { 4216 return child->WmMeasureItem(ctrlId, measureInfo); 4217 } 4218 return mrConsume; 4219 } 4220 4221 /* for WmDrawItem method of Label, Button and Checkbox */ 4222 void AwtComponent::DrawWindowText(HDC hDC, jobject font, jstring text, 4223 int x, int y) 4224 { 4225 int nOldBkMode = ::SetBkMode(hDC,TRANSPARENT); 4226 DASSERT(nOldBkMode != 0); 4227 AwtFont::drawMFString(hDC, font, text, x, y, GetCodePage()); 4228 VERIFY(::SetBkMode(hDC,nOldBkMode)); 4229 } 4230 4231 /* 4232 * Draw text in gray (the color being set to COLOR_GRAYTEXT) when the 4233 * component is disabled. Used only for label, checkbox and button in 4234 * OWNER_DRAW. It draws the text in emboss. 4235 */ 4236 void AwtComponent::DrawGrayText(HDC hDC, jobject font, jstring text, 4237 int x, int y) 4238 { 4239 ::SetTextColor(hDC, ::GetSysColor(COLOR_BTNHILIGHT)); 4240 AwtComponent::DrawWindowText(hDC, font, text, x+1, y+1); 4241 ::SetTextColor(hDC, ::GetSysColor(COLOR_BTNSHADOW)); 4242 AwtComponent::DrawWindowText(hDC, font, text, x, y); 4243 } 4244 4245 /* for WmMeasureItem method of List and Choice */ 4246 jstring AwtComponent::GetItemString(JNIEnv *env, jobject target, jint index) 4247 { 4248 jstring str = (jstring)JNU_CallMethodByName(env, NULL, target, "getItemImpl", 4249 "(I)Ljava/lang/String;", 4250 index).l; 4251 DASSERT(!safe_ExceptionOccurred(env)); 4252 return str; 4253 } 4254 4255 /* for WmMeasureItem method of List and Choice */ 4256 void AwtComponent::MeasureListItem(JNIEnv *env, 4257 MEASUREITEMSTRUCT &measureInfo) 4258 { 4259 if (env->EnsureLocalCapacity(1) < 0) { 4260 return; 4261 } 4262 jobject dimension = PreferredItemSize(env); 4263 DASSERT(dimension); 4264 measureInfo.itemWidth = 4265 env->GetIntField(dimension, AwtDimension::widthID); 4266 measureInfo.itemHeight = 4267 env->GetIntField(dimension, AwtDimension::heightID); 4268 env->DeleteLocalRef(dimension); 4269 } 4270 4271 /* for WmDrawItem method of List and Choice */ 4272 void AwtComponent::DrawListItem(JNIEnv *env, DRAWITEMSTRUCT &drawInfo) 4273 { 4274 if (env->EnsureLocalCapacity(3) < 0) { 4275 return; 4276 } 4277 jobject peer = GetPeer(env); 4278 jobject target = env->GetObjectField(peer, AwtObject::targetID); 4279 4280 HDC hDC = drawInfo.hDC; 4281 RECT rect = drawInfo.rcItem; 4282 4283 BOOL bEnabled = isEnabled(); 4284 BOOL unfocusableChoice = (drawInfo.itemState & ODS_COMBOBOXEDIT) && !IsFocusable(); 4285 DWORD crBack, crText; 4286 if (drawInfo.itemState & ODS_SELECTED){ 4287 /* Set background and text colors for selected item */ 4288 crBack = ::GetSysColor (COLOR_HIGHLIGHT); 4289 crText = ::GetSysColor (COLOR_HIGHLIGHTTEXT); 4290 } else { 4291 /* Set background and text colors for unselected item */ 4292 crBack = GetBackgroundColor(); 4293 crText = bEnabled ? GetColor() : ::GetSysColor(COLOR_GRAYTEXT); 4294 } 4295 if (unfocusableChoice) { 4296 //6190728. Shouldn't draw selection field (edit control) of an owner-drawn combo box. 4297 crBack = GetBackgroundColor(); 4298 crText = bEnabled ? GetColor() : ::GetSysColor(COLOR_GRAYTEXT); 4299 } 4300 4301 /* Fill item rectangle with background color */ 4302 HBRUSH hbrBack = ::CreateSolidBrush (crBack); 4303 DASSERT(hbrBack); 4304 /* 6190728. Shouldn't draw any kind of rectangle around selection field 4305 * (edit control) of an owner-drawn combo box while unfocusable 4306 */ 4307 if (!unfocusableChoice){ 4308 VERIFY(::FillRect (hDC, &rect, hbrBack)); 4309 } 4310 VERIFY(::DeleteObject (hbrBack)); 4311 4312 /* Set current background and text colors */ 4313 ::SetBkColor (hDC, crBack); 4314 ::SetTextColor (hDC, crText); 4315 4316 /*draw string (with left margin of 1 point) */ 4317 if ((int) (drawInfo.itemID) >= 0) { 4318 jobject font = GET_FONT(target, peer); 4319 jstring text = GetItemString(env, target, drawInfo.itemID); 4320 SIZE size = AwtFont::getMFStringSize(hDC, font, text); 4321 AwtFont::drawMFString(hDC, font, text, 4322 (GetRTL()) ? rect.right - size.cx - 1 4323 : rect.left + 1, 4324 (rect.top + rect.bottom - size.cy) / 2, 4325 GetCodePage()); 4326 env->DeleteLocalRef(font); 4327 env->DeleteLocalRef(text); 4328 } 4329 if ((drawInfo.itemState & ODS_FOCUS) && 4330 (drawInfo.itemAction & (ODA_FOCUS | ODA_DRAWENTIRE))) { 4331 if (!unfocusableChoice){ 4332 VERIFY(::DrawFocusRect(hDC, &rect)); 4333 } 4334 } 4335 env->DeleteLocalRef(target); 4336 } 4337 4338 /* for MeasureListItem method and WmDrawItem method of Checkbox */ 4339 jint AwtComponent::GetFontHeight(JNIEnv *env) 4340 { 4341 if (env->EnsureLocalCapacity(4) < 0) { 4342 return NULL; 4343 } 4344 jobject self = GetPeer(env); 4345 jobject target = env->GetObjectField(self, AwtObject::targetID); 4346 4347 jobject font = GET_FONT(target, self); 4348 jobject toolkit = env->CallObjectMethod(target, 4349 AwtComponent::getToolkitMID); 4350 4351 DASSERT(!safe_ExceptionOccurred(env)); 4352 4353 jobject fontMetrics = 4354 env->CallObjectMethod(toolkit, AwtToolkit::getFontMetricsMID, font); 4355 4356 DASSERT(!safe_ExceptionOccurred(env)); 4357 4358 jint height = env->CallIntMethod(fontMetrics, AwtFont::getHeightMID); 4359 DASSERT(!safe_ExceptionOccurred(env)); 4360 4361 env->DeleteLocalRef(target); 4362 env->DeleteLocalRef(font); 4363 env->DeleteLocalRef(toolkit); 4364 env->DeleteLocalRef(fontMetrics); 4365 4366 return height; 4367 } 4368 4369 // If you override WmPrint, make sure to save a copy of the DC on the GDI 4370 // stack to be restored in WmPrintClient. Windows mangles the DC in 4371 // ::DefWindowProc. 4372 MsgRouting AwtComponent::WmPrint(HDC hDC, LPARAM flags) 4373 { 4374 /* 4375 * DefWindowProc for WM_PRINT changes DC parameters, so we have 4376 * to restore it ourselves. Otherwise it will cause problems 4377 * when several components are printed to the same DC. 4378 */ 4379 int nOriginalDC = ::SaveDC(hDC); 4380 DASSERT(nOriginalDC != 0); 4381 4382 if (flags & PRF_NONCLIENT) { 4383 4384 VERIFY(::SaveDC(hDC)); 4385 4386 DefWindowProc(WM_PRINT, (WPARAM)hDC, 4387 (flags & (PRF_NONCLIENT 4388 | PRF_CHECKVISIBLE | PRF_ERASEBKGND))); 4389 4390 VERIFY(::RestoreDC(hDC, -1)); 4391 4392 // Special case for components with a sunken border. Windows does not 4393 // print the border correctly on PCL printers, so we have to do it ourselves. 4394 if (GetStyleEx() & WS_EX_CLIENTEDGE) { 4395 RECT r; 4396 VERIFY(::GetWindowRect(GetHWnd(), &r)); 4397 VERIFY(::OffsetRect(&r, -r.left, -r.top)); 4398 VERIFY(::DrawEdge(hDC, &r, EDGE_SUNKEN, BF_RECT)); 4399 } 4400 } 4401 4402 if (flags & PRF_CLIENT) { 4403 4404 /* 4405 * Special case for components with a sunken border. 4406 * Windows prints a client area without offset to a border width. 4407 * We will first print the non-client area with the original offset, 4408 * then the client area with a corrected offset. 4409 */ 4410 if (GetStyleEx() & WS_EX_CLIENTEDGE) { 4411 4412 int nEdgeWidth = ::GetSystemMetrics(SM_CXEDGE); 4413 int nEdgeHeight = ::GetSystemMetrics(SM_CYEDGE); 4414 4415 VERIFY(::OffsetWindowOrgEx(hDC, -nEdgeWidth, -nEdgeHeight, NULL)); 4416 4417 // Save a copy of the DC for WmPrintClient 4418 VERIFY(::SaveDC(hDC)); 4419 4420 DefWindowProc(WM_PRINT, (WPARAM) hDC, 4421 (flags & (PRF_CLIENT 4422 | PRF_CHECKVISIBLE | PRF_ERASEBKGND))); 4423 4424 VERIFY(::OffsetWindowOrgEx(hDC, nEdgeWidth, nEdgeHeight, NULL)); 4425 4426 } else { 4427 4428 // Save a copy of the DC for WmPrintClient 4429 VERIFY(::SaveDC(hDC)); 4430 DefWindowProc(WM_PRINT, (WPARAM) hDC, 4431 (flags & (PRF_CLIENT 4432 | PRF_CHECKVISIBLE | PRF_ERASEBKGND))); 4433 } 4434 } 4435 4436 if (flags & (PRF_CHILDREN | PRF_OWNED)) { 4437 DefWindowProc(WM_PRINT, (WPARAM) hDC, 4438 (flags & ~PRF_CLIENT & ~PRF_NONCLIENT)); 4439 } 4440 4441 VERIFY(::RestoreDC(hDC, nOriginalDC)); 4442 4443 return mrConsume; 4444 } 4445 4446 // If you override WmPrintClient, make sure to obtain a valid copy of 4447 // the DC from the GDI stack. The copy of the DC should have been placed 4448 // there by WmPrint. Windows mangles the DC in ::DefWindowProc. 4449 MsgRouting AwtComponent::WmPrintClient(HDC hDC, LPARAM) 4450 { 4451 // obtain valid DC from GDI stack 4452 ::RestoreDC(hDC, -1); 4453 4454 return mrDoDefault; 4455 } 4456 4457 MsgRouting AwtComponent::WmNcCalcSize(BOOL fCalcValidRects, 4458 LPNCCALCSIZE_PARAMS lpncsp, 4459 LRESULT &retVal) 4460 { 4461 return mrDoDefault; 4462 } 4463 4464 MsgRouting AwtComponent::WmNcPaint(HRGN hrgn) 4465 { 4466 return mrDoDefault; 4467 } 4468 4469 MsgRouting AwtComponent::WmNcHitTest(UINT x, UINT y, LRESULT &retVal) 4470 { 4471 return mrDoDefault; 4472 } 4473 4474 /** 4475 * WmQueryNewPalette is called whenever our component is coming to 4476 * the foreground; this gives us an opportunity to install our 4477 * custom palette. If this install actually changes entries in 4478 * the system palette, then we get a further call to WmPaletteChanged 4479 * (but note that we only need to realize our palette once). 4480 */ 4481 MsgRouting AwtComponent::WmQueryNewPalette(LRESULT &retVal) 4482 { 4483 int screen = AwtWin32GraphicsDevice::DeviceIndexForWindow(GetHWnd()); 4484 m_QueryNewPaletteCalled = TRUE; 4485 HDC hDC = ::GetDC(GetHWnd()); 4486 DASSERT(hDC); 4487 AwtWin32GraphicsDevice::SelectPalette(hDC, screen); 4488 AwtWin32GraphicsDevice::RealizePalette(hDC, screen); 4489 ::ReleaseDC(GetHWnd(), hDC); 4490 // We must realize the palettes of all of our DC's 4491 // There is sometimes a problem where the realization of 4492 // our temporary hDC here does not actually do what 4493 // we want. Not clear why, but presumably fallout from 4494 // our use of several simultaneous hDC's. 4495 activeDCList.RealizePalettes(screen); 4496 // Do not invalidate here; if the palette 4497 // has not changed we will get an extra repaint 4498 retVal = TRUE; 4499 4500 return mrDoDefault; 4501 } 4502 4503 /** 4504 * We should not need to track this event since we handle our 4505 * palette management effectively in the WmQueryNewPalette and 4506 * WmPaletteChanged methods. However, there seems to be a bug 4507 * on some win32 systems (e.g., NT4) whereby the palette 4508 * immediately after a displayChange is not yet updated to its 4509 * final post-display-change values (hence we adjust our palette 4510 * using the wrong system palette entries), then the palette is 4511 * updated, but a WM_PALETTECHANGED message is never sent. 4512 * By tracking the ISCHANGING message as well (and by tracking 4513 * displayChange events in the AwtToolkit object), we can account 4514 * for this error by forcing our WmPaletteChanged method to be 4515 * called and thereby realizing our logical palette and updating 4516 * our dynamic colorModel object. 4517 */ 4518 MsgRouting AwtComponent::WmPaletteIsChanging(HWND hwndPalChg) 4519 { 4520 if (AwtToolkit::GetInstance().HasDisplayChanged()) { 4521 WmPaletteChanged(hwndPalChg); 4522 AwtToolkit::GetInstance().ResetDisplayChanged(); 4523 } 4524 return mrDoDefault; 4525 } 4526 4527 MsgRouting AwtComponent::WmPaletteChanged(HWND hwndPalChg) 4528 { 4529 // We need to re-realize our palette here (unless we're the one 4530 // that was realizing it in the first place). That will let us match the 4531 // remaining colors in the system palette as best we can. We always 4532 // invalidate because the palette will have changed when we receive this 4533 // message. 4534 4535 int screen = AwtWin32GraphicsDevice::DeviceIndexForWindow(GetHWnd()); 4536 if (hwndPalChg != GetHWnd()) { 4537 HDC hDC = ::GetDC(GetHWnd()); 4538 DASSERT(hDC); 4539 AwtWin32GraphicsDevice::SelectPalette(hDC, screen); 4540 AwtWin32GraphicsDevice::RealizePalette(hDC, screen); 4541 ::ReleaseDC(GetHWnd(), hDC); 4542 // We must realize the palettes of all of our DC's 4543 activeDCList.RealizePalettes(screen); 4544 } 4545 if (AwtWin32GraphicsDevice::UpdateSystemPalette(screen)) { 4546 AwtWin32GraphicsDevice::UpdateDynamicColorModel(screen); 4547 } 4548 Invalidate(NULL); 4549 return mrDoDefault; 4550 } 4551 4552 MsgRouting AwtComponent::WmStyleChanged(int wStyleType, LPSTYLESTRUCT lpss) 4553 { 4554 DASSERT(!IsBadReadPtr(lpss, sizeof(STYLESTRUCT))); 4555 return mrDoDefault; 4556 } 4557 4558 MsgRouting AwtComponent::WmSettingChange(UINT wFlag, LPCTSTR pszSection) 4559 { 4560 DASSERT(!IsBadStringPtr(pszSection, 20)); 4561 DTRACE_PRINTLN2("WM_SETTINGCHANGE: wFlag=%d pszSection=%s", (int)wFlag, pszSection); 4562 return mrDoDefault; 4563 } 4564 4565 HDC AwtComponent::GetDCFromComponent() 4566 { 4567 GetDCReturnStruct *hdcStruct = 4568 (GetDCReturnStruct*)SendMessage(WM_AWT_GETDC); 4569 HDC hdc; 4570 if (hdcStruct) { 4571 if (hdcStruct->gdiLimitReached) { 4572 if (jvm != NULL) { 4573 JNIEnv* env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); 4574 if (env != NULL && !safe_ExceptionOccurred(env)) { 4575 JNU_ThrowByName(env, "java/awt/AWTError", 4576 "HDC creation failure - " \ 4577 "exceeded maximum GDI resources"); 4578 } 4579 } 4580 } 4581 hdc = hdcStruct->hDC; 4582 delete hdcStruct; 4583 } else { 4584 hdc = NULL; 4585 } 4586 return hdc; 4587 } 4588 4589 void AwtComponent::FillBackground(HDC hMemoryDC, SIZE &size) 4590 { 4591 RECT eraseR = { 0, 0, size.cx, size.cy }; 4592 VERIFY(::FillRect(hMemoryDC, &eraseR, GetBackgroundBrush())); 4593 } 4594 4595 void AwtComponent::FillAlpha(void *bitmapBits, SIZE &size, BYTE alpha) 4596 { 4597 if (!bitmapBits) { 4598 return; 4599 } 4600 4601 DWORD* dest = (DWORD*)bitmapBits; 4602 //XXX: might be optimized to use one loop (cy*cx -> 0) 4603 for (int i = 0; i < size.cy; i++ ) { 4604 for (int j = 0; j < size.cx; j++ ) { 4605 ((BYTE*)(dest++))[3] = alpha; 4606 } 4607 } 4608 } 4609 4610 jintArray AwtComponent::CreatePrintedPixels(SIZE &loc, SIZE &size, int alpha) { 4611 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); 4612 4613 if (!::IsWindowVisible(GetHWnd())) { 4614 return NULL; 4615 } 4616 4617 HDC hdc = GetDCFromComponent(); 4618 if (!hdc) { 4619 return NULL; 4620 } 4621 HDC hMemoryDC = ::CreateCompatibleDC(hdc); 4622 void *bitmapBits = NULL; 4623 HBITMAP hBitmap = BitmapUtil::CreateARGBBitmap(size.cx, size.cy, &bitmapBits); 4624 HBITMAP hOldBitmap = (HBITMAP)::SelectObject(hMemoryDC, hBitmap); 4625 SendMessage(WM_AWT_RELEASEDC, (WPARAM)hdc); 4626 4627 FillBackground(hMemoryDC, size); 4628 4629 VERIFY(::SetWindowOrgEx(hMemoryDC, loc.cx, loc.cy, NULL)); 4630 4631 // Don't bother with PRF_CHECKVISIBLE because we called IsWindowVisible 4632 // above. 4633 SendMessage(WM_PRINT, (WPARAM)hMemoryDC, PRF_CLIENT | PRF_NONCLIENT); 4634 4635 // First make sure the system completed any drawing to the bitmap. 4636 ::GdiFlush(); 4637 4638 // WM_PRINT does not fill the alpha-channel of the ARGB bitmap 4639 // leaving it equal to zero. Hence we need to fill it manually. Otherwise 4640 // the pixels will be considered transparent when interpreting the data. 4641 FillAlpha(bitmapBits, size, alpha); 4642 4643 ::SelectObject(hMemoryDC, hOldBitmap); 4644 4645 BITMAPINFO bmi; 4646 memset(&bmi, 0, sizeof(BITMAPINFO)); 4647 bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER); 4648 bmi.bmiHeader.biWidth = size.cx; 4649 bmi.bmiHeader.biHeight = -size.cy; 4650 bmi.bmiHeader.biPlanes = 1; 4651 bmi.bmiHeader.biBitCount = 32; 4652 bmi.bmiHeader.biCompression = BI_RGB; 4653 4654 jobject localPixelArray = env->NewIntArray(size.cx * size.cy); 4655 jintArray pixelArray = NULL; 4656 if (localPixelArray != NULL) { 4657 pixelArray = (jintArray)env->NewGlobalRef(localPixelArray); 4658 env->DeleteLocalRef(localPixelArray); localPixelArray = NULL; 4659 4660 jboolean isCopy; 4661 jint *pixels = env->GetIntArrayElements(pixelArray, &isCopy); 4662 4663 ::GetDIBits(hMemoryDC, hBitmap, 0, size.cy, (LPVOID)pixels, &bmi, 4664 DIB_RGB_COLORS); 4665 4666 env->ReleaseIntArrayElements(pixelArray, pixels, 0); 4667 } 4668 4669 VERIFY(::DeleteObject(hBitmap)); 4670 VERIFY(::DeleteDC(hMemoryDC)); 4671 4672 return pixelArray; 4673 } 4674 4675 void* AwtComponent::SetNativeFocusOwner(void *self) { 4676 if (self == NULL) { 4677 // It means that the KFM wants to set focus to null 4678 sm_focusOwner = NULL; 4679 return NULL; 4680 } 4681 4682 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); 4683 4684 AwtComponent *c = NULL; 4685 jobject peer = (jobject)self; 4686 4687 PDATA pData; 4688 JNI_CHECK_NULL_GOTO(peer, "peer", ret); 4689 pData = JNI_GET_PDATA(peer); 4690 if (pData == NULL) { 4691 goto ret; 4692 } 4693 c = (AwtComponent *)pData; 4694 4695 ret: 4696 if (c && ::IsWindow(c->GetHWnd())) { 4697 sm_focusOwner = c->GetHWnd(); 4698 } else { 4699 sm_focusOwner = NULL; 4700 } 4701 env->DeleteGlobalRef(peer); 4702 return NULL; 4703 } 4704 4705 void* AwtComponent::GetNativeFocusedWindow() { 4706 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); 4707 AwtComponent *comp = 4708 AwtComponent::GetComponent(AwtComponent::GetFocusedWindow()); 4709 return (comp != NULL) ? comp->GetTargetAsGlobalRef(env) : NULL; 4710 } 4711 4712 void* AwtComponent::GetNativeFocusOwner() { 4713 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); 4714 AwtComponent *comp = 4715 AwtComponent::GetComponent(AwtComponent::sm_focusOwner); 4716 return (comp != NULL) ? comp->GetTargetAsGlobalRef(env) : NULL; 4717 } 4718 4719 AwtComponent* AwtComponent::SearchChild(UINT id) { 4720 ChildListItem* child; 4721 for (child = m_childList; child != NULL;child = child->m_next) { 4722 if (child->m_ID == id) 4723 return child->m_Component; 4724 } 4725 /* 4726 * DASSERT(FALSE); 4727 * This should not be happend if all children are recorded 4728 */ 4729 return NULL; /* make compiler happy */ 4730 } 4731 4732 void AwtComponent::RemoveChild(UINT id) { 4733 ChildListItem* child = m_childList; 4734 ChildListItem* lastChild = NULL; 4735 while (child != NULL) { 4736 if (child->m_ID == id) { 4737 if (lastChild == NULL) { 4738 m_childList = child->m_next; 4739 } else { 4740 lastChild->m_next = child->m_next; 4741 } 4742 child->m_next = NULL; 4743 DASSERT(child != NULL); 4744 delete child; 4745 return; 4746 } 4747 lastChild = child; 4748 child = child->m_next; 4749 } 4750 } 4751 4752 void AwtComponent::SendKeyEvent(jint id, jlong when, jint raw, jint cooked, 4753 jint modifiers, jint keyLocation, jlong nativeCode, MSG *pMsg) 4754 { 4755 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); 4756 CriticalSection::Lock l(GetLock()); 4757 if (GetPeer(env) == NULL) { 4758 /* event received during termination. */ 4759 return; 4760 } 4761 4762 static jclass keyEventCls; 4763 if (keyEventCls == NULL) { 4764 jclass keyEventClsLocal = env->FindClass("java/awt/event/KeyEvent"); 4765 DASSERT(keyEventClsLocal); 4766 if (keyEventClsLocal == NULL) { 4767 /* exception already thrown */ 4768 return; 4769 } 4770 keyEventCls = (jclass)env->NewGlobalRef(keyEventClsLocal); 4771 env->DeleteLocalRef(keyEventClsLocal); 4772 } 4773 4774 static jmethodID keyEventConst; 4775 if (keyEventConst == NULL) { 4776 keyEventConst = env->GetMethodID(keyEventCls, "<init>", 4777 "(Ljava/awt/Component;IJIICI)V"); 4778 DASSERT(keyEventConst); 4779 } 4780 if (env->EnsureLocalCapacity(2) < 0) { 4781 return; 4782 } 4783 jobject target = GetTarget(env); 4784 jobject keyEvent = env->NewObject(keyEventCls, keyEventConst, target, 4785 id, when, modifiers, raw, cooked, 4786 keyLocation); 4787 if (safe_ExceptionOccurred(env)) env->ExceptionDescribe(); 4788 DASSERT(!safe_ExceptionOccurred(env)); 4789 DASSERT(keyEvent != NULL); 4790 env->SetLongField(keyEvent, AwtKeyEvent::rawCodeID, nativeCode); 4791 if( nativeCode && nativeCode < 256 ) { 4792 env->SetLongField(keyEvent, AwtKeyEvent::primaryLevelUnicodeID, (jlong)(dynPrimaryKeymap[nativeCode].unicode)); 4793 env->SetLongField(keyEvent, AwtKeyEvent::extendedKeyCodeID, (jlong)(dynPrimaryKeymap[nativeCode].jkey)); 4794 if( nativeCode < 255 ) { 4795 env->SetLongField(keyEvent, AwtKeyEvent::scancodeID, (jlong)(dynPrimaryKeymap[nativeCode].scancode)); 4796 }else if( pMsg != NULL ) { 4797 // unknown key with virtual keycode 0xFF. 4798 // Its scancode is not in the table, pickup it from the message. 4799 env->SetLongField(keyEvent, AwtKeyEvent::scancodeID, (jlong)(HIWORD(pMsg->lParam) & 0xFF)); 4800 } 4801 } 4802 if (pMsg != NULL) { 4803 AwtAWTEvent::saveMSG(env, pMsg, keyEvent); 4804 } 4805 SendEvent(keyEvent); 4806 4807 env->DeleteLocalRef(keyEvent); 4808 env->DeleteLocalRef(target); 4809 } 4810 4811 void 4812 AwtComponent::SendKeyEventToFocusOwner(jint id, jlong when, 4813 jint raw, jint cooked, 4814 jint modifiers, jint keyLocation, 4815 jlong nativeCode, 4816 MSG *msg) 4817 { 4818 /* 4819 * if focus owner is null, but focused window isn't 4820 * we will send key event to focused window 4821 */ 4822 HWND hwndTarget = ((sm_focusOwner != NULL) ? sm_focusOwner : AwtComponent::GetFocusedWindow()); 4823 4824 if (hwndTarget == GetHWnd()) { 4825 SendKeyEvent(id, when, raw, cooked, modifiers, keyLocation, nativeCode, msg); 4826 } else { 4827 AwtComponent *target = NULL; 4828 if (hwndTarget != NULL) { 4829 target = AwtComponent::GetComponent(hwndTarget); 4830 if (target == NULL) { 4831 target = this; 4832 } 4833 } 4834 if (target != NULL) { 4835 target->SendKeyEvent(id, when, raw, cooked, modifiers, 4836 keyLocation, nativeCode, msg); 4837 } 4838 } 4839 } 4840 4841 void AwtComponent::SetDragCapture(UINT flags) 4842 { 4843 // don't want to interfere with other controls 4844 if (::GetCapture() == NULL) { 4845 ::SetCapture(GetHWnd()); 4846 } 4847 } 4848 4849 void AwtComponent::ReleaseDragCapture(UINT flags) 4850 { 4851 if ((::GetCapture() == GetHWnd()) && ((flags & ALL_MK_BUTTONS) == 0)) { 4852 // user has released all buttons, so release the capture 4853 ::ReleaseCapture(); 4854 } 4855 } 4856 4857 void AwtComponent::SendMouseEvent(jint id, jlong when, jint x, jint y, 4858 jint modifiers, jint clickCount, 4859 jboolean popupTrigger, jint button, 4860 MSG *pMsg) 4861 { 4862 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); 4863 CriticalSection::Lock l(GetLock()); 4864 if (GetPeer(env) == NULL) { 4865 /* event received during termination. */ 4866 return; 4867 } 4868 4869 static jclass mouseEventCls; 4870 if (mouseEventCls == NULL) { 4871 jclass mouseEventClsLocal = 4872 env->FindClass("java/awt/event/MouseEvent"); 4873 if (!mouseEventClsLocal) { 4874 /* exception already thrown */ 4875 return; 4876 } 4877 mouseEventCls = (jclass)env->NewGlobalRef(mouseEventClsLocal); 4878 env->DeleteLocalRef(mouseEventClsLocal); 4879 } 4880 RECT insets; 4881 GetInsets(&insets); 4882 4883 static jmethodID mouseEventConst; 4884 if (mouseEventConst == NULL) { 4885 mouseEventConst = 4886 env->GetMethodID(mouseEventCls, "<init>", 4887 "(Ljava/awt/Component;IJIIIIIIZI)V"); 4888 DASSERT(mouseEventConst); 4889 } 4890 if (env->EnsureLocalCapacity(2) < 0) { 4891 return; 4892 } 4893 jobject target = GetTarget(env); 4894 DWORD curMousePos = ::GetMessagePos(); 4895 int xAbs = GET_X_LPARAM(curMousePos); 4896 int yAbs = GET_Y_LPARAM(curMousePos); 4897 jobject mouseEvent = env->NewObject(mouseEventCls, mouseEventConst, 4898 target, 4899 id, when, modifiers, 4900 x+insets.left, y+insets.top, 4901 xAbs, yAbs, 4902 clickCount, popupTrigger, button); 4903 4904 if (safe_ExceptionOccurred(env)) { 4905 env->ExceptionDescribe(); 4906 env->ExceptionClear(); 4907 } 4908 4909 DASSERT(mouseEvent != NULL); 4910 if (pMsg != 0) { 4911 AwtAWTEvent::saveMSG(env, pMsg, mouseEvent); 4912 } 4913 SendEvent(mouseEvent); 4914 4915 env->DeleteLocalRef(mouseEvent); 4916 env->DeleteLocalRef(target); 4917 } 4918 4919 void 4920 AwtComponent::SendMouseWheelEvent(jint id, jlong when, jint x, jint y, 4921 jint modifiers, jint clickCount, 4922 jboolean popupTrigger, jint scrollType, 4923 jint scrollAmount, jint roundedWheelRotation, 4924 jdouble preciseWheelRotation, MSG *pMsg) 4925 { 4926 /* Code based not so loosely on AwtComponent::SendMouseEvent */ 4927 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); 4928 CriticalSection::Lock l(GetLock()); 4929 if (GetPeer(env) == NULL) { 4930 /* event received during termination. */ 4931 return; 4932 } 4933 4934 static jclass mouseWheelEventCls; 4935 if (mouseWheelEventCls == NULL) { 4936 jclass mouseWheelEventClsLocal = 4937 env->FindClass("java/awt/event/MouseWheelEvent"); 4938 if (!mouseWheelEventClsLocal) { 4939 /* exception already thrown */ 4940 return; 4941 } 4942 mouseWheelEventCls = (jclass)env->NewGlobalRef(mouseWheelEventClsLocal); 4943 env->DeleteLocalRef(mouseWheelEventClsLocal); 4944 } 4945 RECT insets; 4946 GetInsets(&insets); 4947 4948 static jmethodID mouseWheelEventConst; 4949 if (mouseWheelEventConst == NULL) { 4950 mouseWheelEventConst = 4951 env->GetMethodID(mouseWheelEventCls, "<init>", 4952 "(Ljava/awt/Component;IJIIIIIIZIIID)V"); 4953 DASSERT(mouseWheelEventConst); 4954 } 4955 if (env->EnsureLocalCapacity(2) < 0) { 4956 return; 4957 } 4958 jobject target = GetTarget(env); 4959 DTRACE_PRINTLN("creating MWE in JNI"); 4960 4961 jobject mouseWheelEvent = env->NewObject(mouseWheelEventCls, 4962 mouseWheelEventConst, 4963 target, 4964 id, when, modifiers, 4965 x+insets.left, y+insets.top, 4966 0, 0, 4967 clickCount, popupTrigger, 4968 scrollType, scrollAmount, 4969 roundedWheelRotation, preciseWheelRotation); 4970 if (safe_ExceptionOccurred(env)) { 4971 env->ExceptionDescribe(); 4972 env->ExceptionClear(); 4973 } 4974 DASSERT(mouseWheelEvent != NULL); 4975 if (pMsg != NULL) { 4976 AwtAWTEvent::saveMSG(env, pMsg, mouseWheelEvent); 4977 } 4978 SendEvent(mouseWheelEvent); 4979 4980 env->DeleteLocalRef(mouseWheelEvent); 4981 env->DeleteLocalRef(target); 4982 } 4983 4984 void AwtComponent::SendFocusEvent(jint id, HWND opposite) 4985 { 4986 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); 4987 4988 CriticalSection::Lock l(GetLock()); 4989 if (GetPeer(env) == NULL) { 4990 /* event received during termination. */ 4991 return; 4992 } 4993 4994 static jclass focusEventCls; 4995 if (focusEventCls == NULL) { 4996 jclass focusEventClsLocal 4997 = env->FindClass("java/awt/event/FocusEvent"); 4998 DASSERT(focusEventClsLocal); 4999 if (focusEventClsLocal == NULL) { 5000 /* exception already thrown */ 5001 return; 5002 } 5003 focusEventCls = (jclass)env->NewGlobalRef(focusEventClsLocal); 5004 env->DeleteLocalRef(focusEventClsLocal); 5005 } 5006 5007 static jmethodID focusEventConst; 5008 if (focusEventConst == NULL) { 5009 focusEventConst = 5010 env->GetMethodID(focusEventCls, "<init>", 5011 "(Ljava/awt/Component;IZLjava/awt/Component;)V"); 5012 DASSERT(focusEventConst); 5013 } 5014 5015 static jclass sequencedEventCls; 5016 if (sequencedEventCls == NULL) { 5017 jclass sequencedEventClsLocal = 5018 env->FindClass("java/awt/SequencedEvent"); 5019 DASSERT(sequencedEventClsLocal); 5020 if (sequencedEventClsLocal == NULL) { 5021 /* exception already thrown */ 5022 return; 5023 } 5024 sequencedEventCls = 5025 (jclass)env->NewGlobalRef(sequencedEventClsLocal); 5026 env->DeleteLocalRef(sequencedEventClsLocal); 5027 } 5028 5029 static jmethodID sequencedEventConst; 5030 if (sequencedEventConst == NULL) { 5031 sequencedEventConst = 5032 env->GetMethodID(sequencedEventCls, "<init>", 5033 "(Ljava/awt/AWTEvent;)V"); 5034 } 5035 5036 if (env->EnsureLocalCapacity(3) < 0) { 5037 return; 5038 } 5039 5040 jobject target = GetTarget(env); 5041 jobject jOpposite = NULL; 5042 if (opposite != NULL) { 5043 AwtComponent *awtOpposite = AwtComponent::GetComponent(opposite); 5044 if (awtOpposite != NULL) { 5045 jOpposite = awtOpposite->GetTarget(env); 5046 } 5047 } 5048 jobject focusEvent = env->NewObject(focusEventCls, focusEventConst, 5049 target, id, JNI_FALSE, jOpposite); 5050 DASSERT(!safe_ExceptionOccurred(env)); 5051 DASSERT(focusEvent != NULL); 5052 if (jOpposite != NULL) { 5053 env->DeleteLocalRef(jOpposite); jOpposite = NULL; 5054 } 5055 env->DeleteLocalRef(target); target = NULL; 5056 5057 jobject sequencedEvent = env->NewObject(sequencedEventCls, 5058 sequencedEventConst, 5059 focusEvent); 5060 DASSERT(!safe_ExceptionOccurred(env)); 5061 DASSERT(sequencedEvent != NULL); 5062 env->DeleteLocalRef(focusEvent); focusEvent = NULL; 5063 5064 SendEvent(sequencedEvent); 5065 5066 env->DeleteLocalRef(sequencedEvent); 5067 } 5068 5069 /* 5070 * Forward a filtered event directly to the subclassed window. 5071 * This method is needed so that DefWindowProc is invoked on the 5072 * component's owning thread. 5073 */ 5074 MsgRouting AwtComponent::HandleEvent(MSG *msg, BOOL) 5075 { 5076 DefWindowProc(msg->message, msg->wParam, msg->lParam); 5077 delete msg; 5078 return mrConsume; 5079 } 5080 5081 /* Post a WM_AWT_HANDLE_EVENT message which invokes HandleEvent 5082 on the toolkit thread. This method may pre-filter the messages. */ 5083 BOOL AwtComponent::PostHandleEventMessage(MSG *msg, BOOL synthetic) 5084 { 5085 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); 5086 // We should cut off keyboard events to disabled components 5087 // to avoid the components responding visually to keystrokes when disabled. 5088 // we shouldn't cut off WM_SYS* messages as they aren't used for normal activity 5089 // but to activate menus, close windows, etc 5090 switch(msg->message) { 5091 case WM_KEYDOWN: 5092 case WM_KEYUP: 5093 case WM_CHAR: 5094 case WM_DEADCHAR: 5095 { 5096 if (!isRecursivelyEnabled()) { 5097 goto quit; 5098 } 5099 break; 5100 } 5101 } 5102 if (PostMessage(GetHWnd(), WM_AWT_HANDLE_EVENT, 5103 (WPARAM) synthetic, (LPARAM) msg)) { 5104 return TRUE; 5105 } else { 5106 JNU_ThrowInternalError(env, "Message not posted, native event queue may be full."); 5107 } 5108 quit: 5109 delete msg; 5110 return FALSE; 5111 } 5112 5113 void AwtComponent::SynthesizeKeyMessage(JNIEnv *env, jobject keyEvent) 5114 { 5115 jint id = (env)->GetIntField(keyEvent, AwtAWTEvent::idID); 5116 UINT message; 5117 switch (id) { 5118 case java_awt_event_KeyEvent_KEY_PRESSED: 5119 message = WM_KEYDOWN; 5120 break; 5121 case java_awt_event_KeyEvent_KEY_RELEASED: 5122 message = WM_KEYUP; 5123 break; 5124 case java_awt_event_KeyEvent_KEY_TYPED: 5125 message = WM_CHAR; 5126 break; 5127 default: 5128 return; 5129 } 5130 5131 /* 5132 * KeyEvent.modifiers aren't supported -- the Java apppwd must send separate 5133 * KEY_PRESSED and KEY_RELEASED events for the modifier virtual keys. 5134 */ 5135 if (id == java_awt_event_KeyEvent_KEY_TYPED) { 5136 // WM_CHAR message must be posted using WM_AWT_FORWARD_CHAR 5137 // (for Edit control) 5138 jchar keyChar = (jchar) 5139 (env)->GetCharField(keyEvent, AwtKeyEvent::keyCharID); 5140 5141 // Bugid 4724007. If it is a Delete character, don't send the fake 5142 // KEY_TYPED we created back to the native window: Windows doesn't 5143 // expect a WM_CHAR for Delete in TextFields, so it tries to enter a 5144 // character after deleting. 5145 if (keyChar == '\177') { // the Delete character 5146 return; 5147 } 5148 5149 // Disable forwarding WM_CHAR messages to disabled components 5150 if (isRecursivelyEnabled()) { 5151 if (!::PostMessage(GetHWnd(), WM_AWT_FORWARD_CHAR, 5152 MAKEWPARAM(keyChar, TRUE), 0)) { 5153 JNU_ThrowInternalError(env, "Message not posted, native event queue may be full."); 5154 } 5155 } 5156 } else { 5157 jint keyCode = 5158 (env)->GetIntField(keyEvent, AwtKeyEvent::keyCodeID); 5159 UINT key, modifiers; 5160 AwtComponent::JavaKeyToWindowsKey(keyCode, &key, &modifiers); 5161 MSG* msg = CreateMessage(message, key, 0); 5162 PostHandleEventMessage(msg, TRUE); 5163 } 5164 } 5165 5166 void AwtComponent::SynthesizeMouseMessage(JNIEnv *env, jobject mouseEvent) 5167 { 5168 /* DebugBreak(); */ 5169 jint button = (env)->GetIntField(mouseEvent, AwtMouseEvent::buttonID); 5170 jint modifiers = (env)->GetIntField(mouseEvent, AwtInputEvent::modifiersID); 5171 5172 WPARAM wParam = 0; 5173 WORD wLow = 0; 5174 jint wheelAmt = 0; 5175 jint id = (env)->GetIntField(mouseEvent, AwtAWTEvent::idID); 5176 UINT message; 5177 switch (id) { 5178 case java_awt_event_MouseEvent_MOUSE_PRESSED: { 5179 switch (button) { 5180 case java_awt_event_MouseEvent_BUTTON1: 5181 message = WM_LBUTTONDOWN; break; 5182 case java_awt_event_MouseEvent_BUTTON3: 5183 message = WM_MBUTTONDOWN; break; 5184 case java_awt_event_MouseEvent_BUTTON2: 5185 message = WM_RBUTTONDOWN; break; 5186 } 5187 break; 5188 } 5189 case java_awt_event_MouseEvent_MOUSE_RELEASED: { 5190 switch (button) { 5191 case java_awt_event_MouseEvent_BUTTON1: 5192 message = WM_LBUTTONUP; break; 5193 case java_awt_event_MouseEvent_BUTTON3: 5194 message = WM_MBUTTONUP; break; 5195 case java_awt_event_MouseEvent_BUTTON2: 5196 message = WM_RBUTTONUP; break; 5197 } 5198 break; 5199 } 5200 case java_awt_event_MouseEvent_MOUSE_MOVED: 5201 /* MOUSE_DRAGGED events must first have sent a MOUSE_PRESSED event. */ 5202 case java_awt_event_MouseEvent_MOUSE_DRAGGED: 5203 message = WM_MOUSEMOVE; 5204 break; 5205 case java_awt_event_MouseEvent_MOUSE_WHEEL: 5206 if (modifiers & java_awt_event_InputEvent_CTRL_DOWN_MASK) { 5207 wLow |= MK_CONTROL; 5208 } 5209 if (modifiers & java_awt_event_InputEvent_SHIFT_DOWN_MASK) { 5210 wLow |= MK_SHIFT; 5211 } 5212 if (modifiers & java_awt_event_InputEvent_BUTTON1_DOWN_MASK) { 5213 wLow |= MK_LBUTTON; 5214 } 5215 if (modifiers & java_awt_event_InputEvent_BUTTON2_DOWN_MASK) { 5216 wLow |= MK_RBUTTON; 5217 } 5218 if (modifiers & java_awt_event_InputEvent_BUTTON3_DOWN_MASK) { 5219 wLow |= MK_MBUTTON; 5220 } 5221 if (modifiers & X1_BUTTON) { 5222 wLow |= GetButtonMK(X1_BUTTON); 5223 } 5224 if (modifiers & X2_BUTTON) { 5225 wLow |= GetButtonMK(X2_BUTTON); 5226 } 5227 5228 wheelAmt = (jint)JNU_CallMethodByName(env, 5229 NULL, 5230 mouseEvent, 5231 "getWheelRotation", 5232 "()I").i; 5233 DASSERT(!safe_ExceptionOccurred(env)); 5234 //DASSERT(wheelAmt); 5235 DTRACE_PRINTLN1("wheelAmt = %i\n", wheelAmt); 5236 5237 // convert Java wheel amount value to Win32 5238 wheelAmt *= -1 * WHEEL_DELTA; 5239 5240 message = WM_MOUSEWHEEL; 5241 wParam = MAKEWPARAM(wLow, wheelAmt); 5242 5243 break; 5244 default: 5245 return; 5246 } 5247 jint x = (env)->GetIntField(mouseEvent, AwtMouseEvent::xID); 5248 jint y = (env)->GetIntField(mouseEvent, AwtMouseEvent::yID); 5249 MSG* msg = CreateMessage(message, wParam, MAKELPARAM(x, y), x, y); 5250 PostHandleEventMessage(msg, TRUE); 5251 } 5252 5253 BOOL AwtComponent::InheritsNativeMouseWheelBehavior() {return false;} 5254 5255 void AwtComponent::Invalidate(RECT* r) 5256 { 5257 ::InvalidateRect(GetHWnd(), r, FALSE); 5258 } 5259 5260 void AwtComponent::BeginValidate() 5261 { 5262 DASSERT(m_validationNestCount >= 0 && 5263 m_validationNestCount < 1000); // sanity check 5264 5265 if (m_validationNestCount == 0) { 5266 // begin deferred window positioning if we're not inside 5267 // another Begin/EndValidate pair 5268 DASSERT(m_hdwp == NULL); 5269 m_hdwp = ::BeginDeferWindowPos(32); 5270 } 5271 5272 m_validationNestCount++; 5273 } 5274 5275 void AwtComponent::EndValidate() 5276 { 5277 DASSERT(m_validationNestCount > 0 && 5278 m_validationNestCount < 1000); // sanity check 5279 DASSERT(m_hdwp != NULL); 5280 5281 m_validationNestCount--; 5282 if (m_validationNestCount == 0) { 5283 // if this call to EndValidate is not nested inside another 5284 // Begin/EndValidate pair, end deferred window positioning 5285 ::EndDeferWindowPos(m_hdwp); 5286 m_hdwp = NULL; 5287 } 5288 } 5289 5290 /** 5291 * HWND, AwtComponent and Java Peer interaction 5292 */ 5293 5294 /* 5295 *Link the C++, Java peer, and HWNDs together. 5296 */ 5297 void AwtComponent::LinkObjects(JNIEnv *env, jobject peer) 5298 { 5299 /* 5300 * Bind all three objects together thru this C++ object, two-way to each: 5301 * JavaPeer <-> C++ <-> HWND 5302 * 5303 * C++ -> JavaPeer 5304 */ 5305 if (m_peerObject == NULL) { 5306 // This may have already been set up by CreateHWnd 5307 // And we don't want to create two references so we 5308 // will leave the prior one alone 5309 m_peerObject = env->NewGlobalRef(peer); 5310 } 5311 /* JavaPeer -> HWND */ 5312 env->SetLongField(peer, AwtComponent::hwndID, reinterpret_cast<jlong>(m_hwnd)); 5313 5314 /* JavaPeer -> C++ */ 5315 JNI_SET_PDATA(peer, this); 5316 5317 /* HWND -> C++ */ 5318 SetComponentInHWND(); 5319 } 5320 5321 /* Cleanup above linking */ 5322 void AwtComponent::UnlinkObjects() 5323 { 5324 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); 5325 if (m_peerObject) { 5326 env->SetLongField(m_peerObject, AwtComponent::hwndID, 0); 5327 JNI_SET_PDATA(m_peerObject, static_cast<PDATA>(NULL)); 5328 JNI_SET_DESTROYED(m_peerObject); 5329 env->DeleteGlobalRef(m_peerObject); 5330 m_peerObject = NULL; 5331 } 5332 } 5333 5334 void AwtComponent::Enable(BOOL bEnable) 5335 { 5336 if (bEnable && IsTopLevel()) { 5337 // we should not enable blocked toplevels 5338 bEnable = !::IsWindow(AwtWindow::GetModalBlocker(GetHWnd())); 5339 } 5340 // Shouldn't trigger native focus change 5341 // (only the proxy may be the native focus owner). 5342 ::EnableWindow(GetHWnd(), bEnable); 5343 5344 CriticalSection::Lock l(GetLock()); 5345 VerifyState(); 5346 } 5347 5348 /* 5349 * associate an AwtDropTarget with this AwtComponent 5350 */ 5351 5352 AwtDropTarget* AwtComponent::CreateDropTarget(JNIEnv* env) { 5353 m_dropTarget = new AwtDropTarget(env, this); 5354 m_dropTarget->RegisterTarget(TRUE); 5355 return m_dropTarget; 5356 } 5357 5358 /* 5359 * disassociate an AwtDropTarget with this AwtComponent 5360 */ 5361 5362 void AwtComponent::DestroyDropTarget() { 5363 if (m_dropTarget != NULL) { 5364 m_dropTarget->RegisterTarget(FALSE); 5365 m_dropTarget->Release(); 5366 m_dropTarget = NULL; 5367 } 5368 } 5369 5370 BOOL AwtComponent::IsFocusingMouseMessage(MSG *pMsg) { 5371 return pMsg->message == WM_LBUTTONDOWN || pMsg->message == WM_LBUTTONDBLCLK; 5372 } 5373 5374 BOOL AwtComponent::IsFocusingKeyMessage(MSG *pMsg) { 5375 return pMsg->message == WM_KEYDOWN && pMsg->wParam == VK_SPACE; 5376 } 5377 5378 void AwtComponent::_Show(void *param) 5379 { 5380 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); 5381 5382 jobject self = (jobject)param; 5383 5384 AwtComponent *p; 5385 5386 PDATA pData; 5387 JNI_CHECK_PEER_GOTO(self, ret); 5388 p = (AwtComponent *)pData; 5389 if (::IsWindow(p->GetHWnd())) 5390 { 5391 p->SendMessage(WM_AWT_COMPONENT_SHOW); 5392 } 5393 ret: 5394 env->DeleteGlobalRef(self); 5395 } 5396 5397 void AwtComponent::_Hide(void *param) 5398 { 5399 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); 5400 5401 jobject self = (jobject)param; 5402 5403 AwtComponent *p; 5404 5405 PDATA pData; 5406 JNI_CHECK_PEER_GOTO(self, ret); 5407 p = (AwtComponent *)pData; 5408 if (::IsWindow(p->GetHWnd())) 5409 { 5410 p->SendMessage(WM_AWT_COMPONENT_HIDE); 5411 } 5412 ret: 5413 env->DeleteGlobalRef(self); 5414 } 5415 5416 void AwtComponent::_Enable(void *param) 5417 { 5418 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); 5419 5420 jobject self = (jobject)param; 5421 5422 AwtComponent *p; 5423 5424 PDATA pData; 5425 JNI_CHECK_PEER_GOTO(self, ret); 5426 p = (AwtComponent *)pData; 5427 if (::IsWindow(p->GetHWnd())) 5428 { 5429 p->Enable(TRUE); 5430 } 5431 ret: 5432 env->DeleteGlobalRef(self); 5433 } 5434 5435 void AwtComponent::_Disable(void *param) 5436 { 5437 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); 5438 5439 jobject self = (jobject)param; 5440 5441 AwtComponent *p; 5442 5443 PDATA pData; 5444 JNI_CHECK_PEER_GOTO(self, ret); 5445 p = (AwtComponent *)pData; 5446 if (::IsWindow(p->GetHWnd())) 5447 { 5448 p->Enable(FALSE); 5449 } 5450 ret: 5451 env->DeleteGlobalRef(self); 5452 } 5453 5454 jobject AwtComponent::_GetLocationOnScreen(void *param) 5455 { 5456 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); 5457 5458 jobject self = (jobject)param; 5459 5460 jobject result = NULL; 5461 AwtComponent *p; 5462 5463 PDATA pData; 5464 JNI_CHECK_PEER_GOTO(self, ret); 5465 p = (AwtComponent *)pData; 5466 if (::IsWindow(p->GetHWnd())) 5467 { 5468 RECT rect; 5469 VERIFY(::GetWindowRect(p->GetHWnd(),&rect)); 5470 result = JNU_NewObjectByName(env, "java/awt/Point", "(II)V", 5471 rect.left, rect.top); 5472 } 5473 ret: 5474 env->DeleteGlobalRef(self); 5475 5476 if (result != NULL) 5477 { 5478 jobject resultGlobalRef = env->NewGlobalRef(result); 5479 env->DeleteLocalRef(result); 5480 return resultGlobalRef; 5481 } 5482 else 5483 { 5484 return NULL; 5485 } 5486 } 5487 5488 void AwtComponent::_Reshape(void *param) 5489 { 5490 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); 5491 5492 ReshapeStruct *rs = (ReshapeStruct*)param; 5493 jobject self = rs->component; 5494 jint x = rs->x; 5495 jint y = rs->y; 5496 jint w = rs->w; 5497 jint h = rs->h; 5498 5499 AwtComponent *p; 5500 5501 PDATA pData; 5502 JNI_CHECK_PEER_GOTO(self, ret); 5503 p = (AwtComponent *)pData; 5504 if (::IsWindow(p->GetHWnd())) 5505 { 5506 RECT* r = new RECT; 5507 ::SetRect(r, x, y, x + w, y + h); 5508 p->SendMessage(WM_AWT_RESHAPE_COMPONENT, CHECK_EMBEDDED, (LPARAM)r); 5509 } 5510 ret: 5511 env->DeleteGlobalRef(self); 5512 5513 delete rs; 5514 } 5515 5516 void AwtComponent::_ReshapeNoCheck(void *param) 5517 { 5518 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); 5519 5520 ReshapeStruct *rs = (ReshapeStruct*)param; 5521 jobject self = rs->component; 5522 jint x = rs->x; 5523 jint y = rs->y; 5524 jint w = rs->w; 5525 jint h = rs->h; 5526 5527 AwtComponent *p; 5528 5529 PDATA pData; 5530 JNI_CHECK_PEER_GOTO(self, ret); 5531 p = (AwtComponent *)pData; 5532 if (::IsWindow(p->GetHWnd())) 5533 { 5534 RECT* r = new RECT; 5535 ::SetRect(r, x, y, x + w, y + h); 5536 p->SendMessage(WM_AWT_RESHAPE_COMPONENT, DONT_CHECK_EMBEDDED, (LPARAM)r); 5537 } 5538 ret: 5539 env->DeleteGlobalRef(self); 5540 5541 delete rs; 5542 } 5543 5544 void AwtComponent::_NativeHandleEvent(void *param) 5545 { 5546 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); 5547 5548 NativeHandleEventStruct *nhes = (NativeHandleEventStruct *)param; 5549 jobject self = nhes->component; 5550 jobject event = nhes->event; 5551 5552 AwtComponent *p; 5553 5554 PDATA pData; 5555 JNI_CHECK_NULL_GOTO(self, "peer", ret); 5556 pData = JNI_GET_PDATA(self); 5557 if (pData == NULL) { 5558 env->DeleteGlobalRef(self); 5559 if (event != NULL) { 5560 env->DeleteGlobalRef(event); 5561 } 5562 delete nhes; 5563 return; 5564 } 5565 JNI_CHECK_NULL_GOTO(event, "null AWTEvent", ret); 5566 5567 p = (AwtComponent *)pData; 5568 if (::IsWindow(p->GetHWnd())) 5569 { 5570 if (env->EnsureLocalCapacity(1) < 0) { 5571 env->DeleteGlobalRef(self); 5572 env->DeleteGlobalRef(event); 5573 delete nhes; 5574 return; 5575 } 5576 jbyteArray bdata = (jbyteArray)(env)->GetObjectField(event, AwtAWTEvent::bdataID); 5577 int id = (env)->GetIntField(event, AwtAWTEvent::idID); 5578 DASSERT(!safe_ExceptionOccurred(env)); 5579 if (bdata != 0) { 5580 MSG msg; 5581 (env)->GetByteArrayRegion(bdata, 0, sizeof(MSG), (jbyte *)&msg); 5582 (env)->DeleteLocalRef(bdata); 5583 static BOOL keyDownConsumed = FALSE; 5584 static BOOL bCharChanged = FALSE; 5585 static WCHAR modifiedChar; 5586 WCHAR unicodeChar; 5587 5588 /* Remember if a KEY_PRESSED event is consumed, as an old model 5589 * program won't consume a subsequent KEY_TYPED event. 5590 */ 5591 jboolean consumed = 5592 (env)->GetBooleanField(event, AwtAWTEvent::consumedID); 5593 DASSERT(!safe_ExceptionOccurred(env)); 5594 5595 if (consumed) { 5596 keyDownConsumed = (id == java_awt_event_KeyEvent_KEY_PRESSED); 5597 env->DeleteGlobalRef(self); 5598 env->DeleteGlobalRef(event); 5599 delete nhes; 5600 return; 5601 5602 } else if (id == java_awt_event_KeyEvent_KEY_PRESSED) { 5603 // Fix for 6637607: reset consuming 5604 keyDownConsumed = FALSE; 5605 } 5606 5607 /* Consume a KEY_TYPED event if a KEY_PRESSED had been, to support 5608 * the old model. 5609 */ 5610 if ((id == java_awt_event_KeyEvent_KEY_TYPED) && keyDownConsumed) { 5611 keyDownConsumed = FALSE; 5612 env->DeleteGlobalRef(self); 5613 env->DeleteGlobalRef(event); 5614 delete nhes; 5615 return; 5616 } 5617 5618 /* Modify any event parameters, if necessary. */ 5619 if (self && pData && 5620 id >= java_awt_event_KeyEvent_KEY_FIRST && 5621 id <= java_awt_event_KeyEvent_KEY_LAST) { 5622 5623 AwtComponent* p = (AwtComponent*)pData; 5624 5625 jint keyCode = 5626 (env)->GetIntField(event, AwtKeyEvent::keyCodeID); 5627 jchar keyChar = 5628 (env)->GetCharField(event, AwtKeyEvent::keyCharID); 5629 jint modifiers = 5630 (env)->GetIntField(event, AwtInputEvent::modifiersID); 5631 5632 DASSERT(!safe_ExceptionOccurred(env)); 5633 5634 /* Check to see whether the keyCode or modifiers were changed 5635 on the keyPressed event, and tweak the following keyTyped 5636 event (if any) accodingly. */ 5637 switch (id) { 5638 case java_awt_event_KeyEvent_KEY_PRESSED: 5639 { 5640 UINT winKey = (UINT)msg.wParam; 5641 bCharChanged = FALSE; 5642 5643 if (winKey == VK_PROCESSKEY) { 5644 // Leave it up to IME 5645 break; 5646 } 5647 5648 if (keyCode != java_awt_event_KeyEvent_VK_UNDEFINED) { 5649 UINT newWinKey, ignored; 5650 p->JavaKeyToWindowsKey(keyCode, &newWinKey, &ignored, winKey); 5651 if (newWinKey != 0) { 5652 winKey = newWinKey; 5653 } 5654 } 5655 5656 BOOL isDeadKey = FALSE; 5657 modifiedChar = p->WindowsKeyToJavaChar(winKey, modifiers, AwtComponent::NONE, isDeadKey); 5658 bCharChanged = (keyChar != modifiedChar); 5659 } 5660 break; 5661 5662 case java_awt_event_KeyEvent_KEY_RELEASED: 5663 { 5664 keyDownConsumed = FALSE; 5665 bCharChanged = FALSE; 5666 } 5667 break; 5668 5669 case java_awt_event_KeyEvent_KEY_TYPED: 5670 { 5671 if (bCharChanged) 5672 { 5673 unicodeChar = modifiedChar; 5674 } 5675 else 5676 { 5677 unicodeChar = keyChar; 5678 } 5679 bCharChanged = FALSE; 5680 5681 // Disable forwarding KEY_TYPED messages to peers of 5682 // disabled components 5683 if (p->isRecursivelyEnabled()) { 5684 // send the character back to the native window for 5685 // processing. The WM_AWT_FORWARD_CHAR handler will send 5686 // this character to DefWindowProc 5687 if (!::PostMessage(p->GetHWnd(), WM_AWT_FORWARD_CHAR, 5688 MAKEWPARAM(unicodeChar, FALSE), msg.lParam)) { 5689 JNU_ThrowInternalError(env, "Message not posted, native event queue may be full."); 5690 } 5691 } 5692 env->DeleteGlobalRef(self); 5693 env->DeleteGlobalRef(event); 5694 delete nhes; 5695 return; 5696 } 5697 break; 5698 5699 default: 5700 break; 5701 } 5702 } 5703 5704 // ignore all InputMethodEvents 5705 if (self && (pData = JNI_GET_PDATA(self)) && 5706 id >= java_awt_event_InputMethodEvent_INPUT_METHOD_FIRST && 5707 id <= java_awt_event_InputMethodEvent_INPUT_METHOD_LAST) { 5708 env->DeleteGlobalRef(self); 5709 env->DeleteGlobalRef(event); 5710 delete nhes; 5711 return; 5712 } 5713 5714 // Create copy for local msg 5715 MSG* pCopiedMsg = new MSG; 5716 memmove(pCopiedMsg, &msg, sizeof(MSG)); 5717 // Event handler deletes msg 5718 p->PostHandleEventMessage(pCopiedMsg, FALSE); 5719 5720 env->DeleteGlobalRef(self); 5721 env->DeleteGlobalRef(event); 5722 delete nhes; 5723 return; 5724 } 5725 5726 /* Forward any valid synthesized events. Currently only mouse and 5727 * key events are supported. 5728 */ 5729 if (self == NULL || (pData = JNI_GET_PDATA(self)) == NULL) { 5730 env->DeleteGlobalRef(self); 5731 env->DeleteGlobalRef(event); 5732 delete nhes; 5733 return; 5734 } 5735 5736 AwtComponent* p = (AwtComponent*)pData; 5737 if (id >= java_awt_event_KeyEvent_KEY_FIRST && 5738 id <= java_awt_event_KeyEvent_KEY_LAST) { 5739 p->SynthesizeKeyMessage(env, event); 5740 } else if (id >= java_awt_event_MouseEvent_MOUSE_FIRST && 5741 id <= java_awt_event_MouseEvent_MOUSE_LAST) { 5742 p->SynthesizeMouseMessage(env, event); 5743 } 5744 } 5745 5746 ret: 5747 if (self != NULL) { 5748 env->DeleteGlobalRef(self); 5749 } 5750 if (event != NULL) { 5751 env->DeleteGlobalRef(event); 5752 } 5753 5754 delete nhes; 5755 } 5756 5757 void AwtComponent::_SetForeground(void *param) 5758 { 5759 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); 5760 5761 SetColorStruct *scs = (SetColorStruct *)param; 5762 jobject self = scs->component; 5763 jint rgb = scs->rgb; 5764 5765 AwtComponent *c = NULL; 5766 5767 PDATA pData; 5768 JNI_CHECK_PEER_GOTO(self, ret); 5769 c = (AwtComponent *)pData; 5770 if (::IsWindow(c->GetHWnd())) 5771 { 5772 c->SetColor(PALETTERGB((rgb>>16)&0xff, 5773 (rgb>>8)&0xff, 5774 (rgb)&0xff)); 5775 c->VerifyState(); 5776 } 5777 ret: 5778 env->DeleteGlobalRef(self); 5779 5780 delete scs; 5781 } 5782 5783 void AwtComponent::_SetBackground(void *param) 5784 { 5785 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); 5786 5787 SetColorStruct *scs = (SetColorStruct *)param; 5788 jobject self = scs->component; 5789 jint rgb = scs->rgb; 5790 5791 AwtComponent *c = NULL; 5792 5793 PDATA pData; 5794 JNI_CHECK_PEER_GOTO(self, ret); 5795 c = (AwtComponent *)pData; 5796 if (::IsWindow(c->GetHWnd())) 5797 { 5798 c->SetBackgroundColor(PALETTERGB((rgb>>16)&0xff, 5799 (rgb>>8)&0xff, 5800 (rgb)&0xff)); 5801 c->VerifyState(); 5802 } 5803 ret: 5804 env->DeleteGlobalRef(self); 5805 5806 delete scs; 5807 } 5808 5809 void AwtComponent::_SetFont(void *param) 5810 { 5811 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); 5812 5813 SetFontStruct *sfs = (SetFontStruct *)param; 5814 jobject self = sfs->component; 5815 jobject font = sfs->font; 5816 5817 AwtComponent *c = NULL; 5818 5819 PDATA pData; 5820 JNI_CHECK_PEER_GOTO(self, ret); 5821 JNI_CHECK_NULL_GOTO(font, "null font", ret); 5822 c = (AwtComponent *)pData; 5823 if (::IsWindow(c->GetHWnd())) 5824 { 5825 AwtFont *awtFont = (AwtFont *)env->GetLongField(font, AwtFont::pDataID); 5826 if (awtFont == NULL) { 5827 /*arguments of AwtFont::Create are changed for multifont component */ 5828 awtFont = AwtFont::Create(env, font); 5829 } 5830 env->SetLongField(font, AwtFont::pDataID, (jlong)awtFont); 5831 5832 c->SetFont(awtFont); 5833 } 5834 ret: 5835 env->DeleteGlobalRef(self); 5836 env->DeleteGlobalRef(font); 5837 5838 delete sfs; 5839 } 5840 5841 // Sets or kills focus for a component. 5842 void AwtComponent::_SetFocus(void *param) 5843 { 5844 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); 5845 5846 SetFocusStruct *sfs = (SetFocusStruct *)param; 5847 jobject self = sfs->component; 5848 jboolean doSetFocus = sfs->doSetFocus; 5849 5850 AwtComponent *c = NULL; 5851 5852 PDATA pData; 5853 JNI_CHECK_NULL_GOTO(self, "peer", ret); 5854 pData = JNI_GET_PDATA(self); 5855 if (pData == NULL) { 5856 // do nothing just return false 5857 goto ret; 5858 } 5859 5860 c = (AwtComponent *)pData; 5861 if (::IsWindow(c->GetHWnd())) { 5862 c->SendMessage(WM_AWT_COMPONENT_SETFOCUS, (WPARAM)doSetFocus, 0); 5863 } 5864 ret: 5865 env->DeleteGlobalRef(self); 5866 5867 delete sfs; 5868 } 5869 5870 void AwtComponent::_Start(void *param) 5871 { 5872 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); 5873 5874 jobject self = (jobject)param; 5875 5876 AwtComponent *c = NULL; 5877 5878 PDATA pData; 5879 JNI_CHECK_PEER_GOTO(self, ret); 5880 c = (AwtComponent *)pData; 5881 if (::IsWindow(c->GetHWnd())) 5882 { 5883 jobject target = c->GetTarget(env); 5884 5885 /* Disable window if specified -- windows are enabled by default. */ 5886 jboolean enabled = (jboolean)env->GetBooleanField(target, 5887 AwtComponent::enabledID); 5888 if (!enabled) { 5889 ::EnableWindow(c->GetHWnd(), FALSE); 5890 } 5891 5892 /* The peer is now ready for callbacks, since this is the last 5893 * initialization call 5894 */ 5895 c->EnableCallbacks(TRUE); 5896 5897 // Fix 4745222: we need to invalidate region since we validated it before initialization. 5898 ::InvalidateRgn(c->GetHWnd(), NULL, FALSE); 5899 5900 // Fix 4530093: WM_PAINT after EnableCallbacks 5901 ::UpdateWindow(c->GetHWnd()); 5902 5903 env->DeleteLocalRef(target); 5904 } 5905 ret: 5906 env->DeleteGlobalRef(self); 5907 } 5908 5909 void AwtComponent::_BeginValidate(void *param) 5910 { 5911 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); 5912 if (AwtToolkit::IsMainThread()) { 5913 jobject self = (jobject)param; 5914 if (self != NULL) { 5915 PDATA pData = JNI_GET_PDATA(self); 5916 if (pData) { 5917 AwtComponent *c = (AwtComponent *)pData; 5918 if (::IsWindow(c->GetHWnd())) { 5919 c->SendMessage(WM_AWT_BEGIN_VALIDATE); 5920 } 5921 } 5922 env->DeleteGlobalRef(self); 5923 } 5924 } else { 5925 AwtToolkit::GetInstance().InvokeFunction(AwtComponent::_BeginValidate, param); 5926 } 5927 } 5928 5929 void AwtComponent::_EndValidate(void *param) 5930 { 5931 if (AwtToolkit::IsMainThread()) { 5932 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); 5933 jobject self = (jobject)param; 5934 if (self != NULL) { 5935 PDATA pData = JNI_GET_PDATA(self); 5936 if (pData) { 5937 AwtComponent *c = (AwtComponent *)pData; 5938 if (::IsWindow(c->GetHWnd())) { 5939 c->SendMessage(WM_AWT_END_VALIDATE); 5940 } 5941 } 5942 env->DeleteGlobalRef(self); 5943 } 5944 } else { 5945 AwtToolkit::GetInstance().InvokeFunction(AwtComponent::_EndValidate, param); 5946 } 5947 } 5948 5949 void AwtComponent::_UpdateWindow(void *param) 5950 { 5951 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); 5952 if (AwtToolkit::IsMainThread()) { 5953 jobject self = (jobject)param; 5954 AwtComponent *c = NULL; 5955 PDATA pData; 5956 JNI_CHECK_PEER_GOTO(self, ret); 5957 c = (AwtComponent *)pData; 5958 if (::IsWindow(c->GetHWnd())) { 5959 ::UpdateWindow(c->GetHWnd()); 5960 } 5961 ret: 5962 env->DeleteGlobalRef(self); 5963 } else { 5964 AwtToolkit::GetInstance().InvokeFunction(AwtComponent::_UpdateWindow, param); 5965 } 5966 } 5967 5968 jlong AwtComponent::_AddNativeDropTarget(void *param) 5969 { 5970 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); 5971 5972 jobject self = (jobject)param; 5973 5974 jlong result = 0; 5975 AwtComponent *c = NULL; 5976 5977 PDATA pData; 5978 JNI_CHECK_PEER_GOTO(self, ret); 5979 c = (AwtComponent *)pData; 5980 if (::IsWindow(c->GetHWnd())) 5981 { 5982 result = (jlong)(c->CreateDropTarget(env)); 5983 } 5984 ret: 5985 env->DeleteGlobalRef(self); 5986 5987 return result; 5988 } 5989 5990 void AwtComponent::_RemoveNativeDropTarget(void *param) 5991 { 5992 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); 5993 5994 jobject self = (jobject)param; 5995 5996 AwtComponent *c = NULL; 5997 5998 PDATA pData; 5999 JNI_CHECK_PEER_GOTO(self, ret); 6000 c = (AwtComponent *)pData; 6001 if (::IsWindow(c->GetHWnd())) 6002 { 6003 c->DestroyDropTarget(); 6004 } 6005 ret: 6006 env->DeleteGlobalRef(self); 6007 } 6008 6009 jintArray AwtComponent::_CreatePrintedPixels(void *param) 6010 { 6011 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); 6012 6013 CreatePrintedPixelsStruct *cpps = (CreatePrintedPixelsStruct *)param; 6014 jobject self = cpps->component; 6015 6016 jintArray result = NULL; 6017 AwtComponent *c = NULL; 6018 6019 PDATA pData; 6020 JNI_CHECK_PEER_GOTO(self, ret); 6021 c = (AwtComponent *)pData; 6022 if (::IsWindow(c->GetHWnd())) 6023 { 6024 result = (jintArray)c->SendMessage(WM_AWT_CREATE_PRINTED_PIXELS, (WPARAM)cpps, 0); 6025 } 6026 ret: 6027 env->DeleteGlobalRef(self); 6028 6029 delete cpps; 6030 return result; // this reference is global 6031 } 6032 6033 jboolean AwtComponent::_IsObscured(void *param) 6034 { 6035 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); 6036 6037 jobject self = (jobject)param; 6038 6039 jboolean result = JNI_FALSE; 6040 AwtComponent *c = NULL; 6041 6042 PDATA pData; 6043 JNI_CHECK_PEER_GOTO(self, ret); 6044 6045 c = (AwtComponent *)pData; 6046 6047 if (::IsWindow(c->GetHWnd())) 6048 { 6049 HWND hWnd = c->GetHWnd(); 6050 HDC hDC = ::GetDC(hWnd); 6051 RECT clipbox; 6052 int callresult = ::GetClipBox(hDC, &clipbox); 6053 switch(callresult) { 6054 case NULLREGION : 6055 result = JNI_FALSE; 6056 break; 6057 case SIMPLEREGION : { 6058 RECT windowRect; 6059 if (!::GetClientRect(hWnd, &windowRect)) { 6060 result = JNI_TRUE; 6061 } else { 6062 result = (jboolean)((clipbox.bottom != windowRect.bottom) 6063 || (clipbox.left != windowRect.left) 6064 || (clipbox.right != windowRect.right) 6065 || (clipbox.top != windowRect.top)); 6066 } 6067 break; 6068 } 6069 case COMPLEXREGION : 6070 default : 6071 result = JNI_TRUE; 6072 break; 6073 } 6074 ::ReleaseDC(hWnd, hDC); 6075 } 6076 ret: 6077 env->DeleteGlobalRef(self); 6078 6079 return result; 6080 } 6081 6082 jboolean AwtComponent::_NativeHandlesWheelScrolling(void *param) 6083 { 6084 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); 6085 6086 jobject self = (jobject)param; 6087 6088 jboolean result = JNI_FALSE; 6089 AwtComponent *c = NULL; 6090 6091 PDATA pData; 6092 JNI_CHECK_PEER_GOTO(self, ret); 6093 c = (AwtComponent *)pData; 6094 if (::IsWindow(c->GetHWnd())) 6095 { 6096 result = (jboolean)c->InheritsNativeMouseWheelBehavior(); 6097 } 6098 ret: 6099 env->DeleteGlobalRef(self); 6100 6101 return result; 6102 } 6103 6104 void AwtComponent::SetParent(void * param) { 6105 if (AwtToolkit::IsMainThread()) { 6106 AwtComponent** comps = (AwtComponent**)param; 6107 if ((comps[0] != NULL) && (comps[1] != NULL)) { 6108 HWND selfWnd = comps[0]->GetHWnd(); 6109 HWND parentWnd = comps[1]->GetHWnd(); 6110 if (::IsWindow(selfWnd) && ::IsWindow(parentWnd)) { 6111 // Shouldn't trigger native focus change 6112 // (only the proxy may be the native focus owner). 6113 ::SetParent(selfWnd, parentWnd); 6114 } 6115 } 6116 delete[] comps; 6117 } else { 6118 AwtToolkit::GetInstance().InvokeFunction(AwtComponent::SetParent, param); 6119 } 6120 } 6121 6122 void AwtComponent::_SetRectangularShape(void *param) 6123 { 6124 if (!AwtToolkit::IsMainThread()) { 6125 AwtToolkit::GetInstance().InvokeFunction(AwtComponent::_SetRectangularShape, param); 6126 } else { 6127 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); 6128 6129 SetRectangularShapeStruct *data = (SetRectangularShapeStruct *)param; 6130 jobject self = data->component; 6131 jint x1 = data->x1; 6132 jint x2 = data->x2; 6133 jint y1 = data->y1; 6134 jint y2 = data->y2; 6135 jobject region = data->region; 6136 6137 AwtComponent *c = NULL; 6138 6139 PDATA pData; 6140 JNI_CHECK_PEER_GOTO(self, ret); 6141 6142 c = (AwtComponent *)pData; 6143 if (::IsWindow(c->GetHWnd())) { 6144 HRGN hRgn = NULL; 6145 6146 // If all the params are zeros, the shape must be simply reset. 6147 // Otherwise, convert it into a region. 6148 if (region || x1 || x2 || y1 || y2) { 6149 RECT_T rects[256]; 6150 RECT_T *pRect = rects; 6151 6152 const int numrects = RegionToYXBandedRectangles(env, x1, y1, x2, y2, 6153 region, &pRect, sizeof(rects)/sizeof(rects[0])); 6154 if (!pRect) { 6155 // RegionToYXBandedRectangles doesn't use safe_Malloc(), 6156 // so throw the exception explicitly 6157 throw std::bad_alloc(); 6158 } 6159 6160 RGNDATA *pRgnData = (RGNDATA *) SAFE_SIZE_STRUCT_ALLOC(safe_Malloc, 6161 sizeof(RGNDATAHEADER), sizeof(RECT_T), numrects); 6162 memcpy((BYTE*)pRgnData + sizeof(RGNDATAHEADER), pRect, sizeof(RECT_T) * numrects); 6163 if (pRect != rects) { 6164 free(pRect); 6165 } 6166 pRect = NULL; 6167 6168 RGNDATAHEADER *pRgnHdr = (RGNDATAHEADER *) pRgnData; 6169 pRgnHdr->dwSize = sizeof(RGNDATAHEADER); 6170 pRgnHdr->iType = RDH_RECTANGLES; 6171 pRgnHdr->nRgnSize = 0; 6172 pRgnHdr->rcBound.top = 0; 6173 pRgnHdr->rcBound.left = 0; 6174 pRgnHdr->rcBound.bottom = LONG(y2 - y1); 6175 pRgnHdr->rcBound.right = LONG(x2 - x1); 6176 pRgnHdr->nCount = numrects; 6177 6178 hRgn = ::ExtCreateRegion(NULL, 6179 sizeof(RGNDATAHEADER) + sizeof(RECT_T) * pRgnHdr->nCount, pRgnData); 6180 6181 free(pRgnData); 6182 } 6183 6184 ::SetWindowRgn(c->GetHWnd(), hRgn, TRUE); 6185 } 6186 6187 ret: 6188 env->DeleteGlobalRef(self); 6189 if (region) { 6190 env->DeleteGlobalRef(region); 6191 } 6192 6193 delete data; 6194 } 6195 } 6196 6197 void AwtComponent::_SetZOrder(void *param) { 6198 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); 6199 6200 SetZOrderStruct *data = (SetZOrderStruct *)param; 6201 jobject self = data->component; 6202 HWND above = HWND_TOP; 6203 if (data->above != 0) { 6204 above = reinterpret_cast<HWND>(data->above); 6205 } 6206 6207 AwtComponent *c = NULL; 6208 6209 PDATA pData; 6210 JNI_CHECK_PEER_GOTO(self, ret); 6211 6212 c = (AwtComponent *)pData; 6213 if (::IsWindow(c->GetHWnd())) { 6214 ::SetWindowPos(c->GetHWnd(), above, 0, 0, 0, 0, 6215 SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE | SWP_DEFERERASE | SWP_ASYNCWINDOWPOS); 6216 } 6217 6218 ret: 6219 env->DeleteGlobalRef(self); 6220 6221 delete data; 6222 } 6223 6224 void AwtComponent::PostUngrabEvent() { 6225 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); 6226 jobject target = GetTarget(env); 6227 jobject event = JNU_NewObjectByName(env, "sun/awt/UngrabEvent", "(Ljava/awt/Component;)V", 6228 target); 6229 if (safe_ExceptionOccurred(env)) { 6230 env->ExceptionDescribe(); 6231 env->ExceptionClear(); 6232 } 6233 env->DeleteLocalRef(target); 6234 if (event != NULL) { 6235 SendEvent(event); 6236 env->DeleteLocalRef(event); 6237 } 6238 } 6239 6240 void AwtComponent::SetFocusedWindow(HWND window) 6241 { 6242 HWND old = sm_focusedWindow; 6243 sm_focusedWindow = window; 6244 6245 AwtWindow::FocusedWindowChanged(old, window); 6246 } 6247 6248 /************************************************************************ 6249 * Component native methods 6250 */ 6251 6252 extern "C" { 6253 6254 /** 6255 * This method is called from the WGL pipeline when it needs to retrieve 6256 * the HWND associated with a ComponentPeer's C++ level object. 6257 */ 6258 HWND 6259 AwtComponent_GetHWnd(JNIEnv *env, jlong pData) 6260 { 6261 AwtComponent *p = (AwtComponent *)jlong_to_ptr(pData); 6262 if (p == NULL) { 6263 return (HWND)0; 6264 } 6265 return p->GetHWnd(); 6266 } 6267 6268 static void _GetInsets(void* param) 6269 { 6270 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); 6271 6272 GetInsetsStruct *gis = (GetInsetsStruct *)param; 6273 jobject self = gis->window; 6274 6275 gis->insets->left = gis->insets->top = 6276 gis->insets->right = gis->insets->bottom = 0; 6277 6278 PDATA pData; 6279 JNI_CHECK_PEER_GOTO(self, ret); 6280 AwtComponent *component = (AwtComponent *)pData; 6281 6282 component->GetInsets(gis->insets); 6283 6284 ret: 6285 env->DeleteGlobalRef(self); 6286 delete gis; 6287 } 6288 6289 /** 6290 * This method is called from the WGL pipeline when it needs to retrieve 6291 * the insets associated with a ComponentPeer's C++ level object. 6292 */ 6293 void AwtComponent_GetInsets(JNIEnv *env, jobject peer, RECT *insets) 6294 { 6295 TRY; 6296 6297 GetInsetsStruct *gis = new GetInsetsStruct; 6298 gis->window = env->NewGlobalRef(peer); 6299 gis->insets = insets; 6300 6301 AwtToolkit::GetInstance().InvokeFunction(_GetInsets, gis); 6302 // global refs and mds are deleted in _UpdateWindow 6303 6304 CATCH_BAD_ALLOC; 6305 6306 } 6307 6308 JNIEXPORT void JNICALL 6309 Java_java_awt_Component_initIDs(JNIEnv *env, jclass cls) 6310 { 6311 TRY; 6312 jclass inputEventClazz = env->FindClass("java/awt/event/InputEvent"); 6313 jmethodID getButtonDownMasksID = env->GetStaticMethodID(inputEventClazz, "getButtonDownMasks", "()[I"); 6314 jintArray obj = (jintArray)env->CallStaticObjectMethod(inputEventClazz, getButtonDownMasksID); 6315 jint * tmp = env->GetIntArrayElements(obj, JNI_FALSE); 6316 6317 jsize len = env->GetArrayLength(obj); 6318 AwtComponent::masks = SAFE_SIZE_NEW_ARRAY(jint, len); 6319 for (int i = 0; i < len; i++) { 6320 AwtComponent::masks[i] = tmp[i]; 6321 } 6322 env->ReleaseIntArrayElements(obj, tmp, 0); 6323 env->DeleteLocalRef(obj); 6324 6325 /* class ids */ 6326 jclass peerCls = env->FindClass("sun/awt/windows/WComponentPeer"); 6327 6328 DASSERT(peerCls); 6329 6330 /* field ids */ 6331 AwtComponent::peerID = 6332 env->GetFieldID(cls, "peer", "Ljava/awt/peer/ComponentPeer;"); 6333 AwtComponent::xID = env->GetFieldID(cls, "x", "I"); 6334 AwtComponent::yID = env->GetFieldID(cls, "y", "I"); 6335 AwtComponent::heightID = env->GetFieldID(cls, "height", "I"); 6336 AwtComponent::widthID = env->GetFieldID(cls, "width", "I"); 6337 AwtComponent::visibleID = env->GetFieldID(cls, "visible", "Z"); 6338 AwtComponent::backgroundID = 6339 env->GetFieldID(cls, "background", "Ljava/awt/Color;"); 6340 AwtComponent::foregroundID = 6341 env->GetFieldID(cls, "foreground", "Ljava/awt/Color;"); 6342 AwtComponent::enabledID = env->GetFieldID(cls, "enabled", "Z"); 6343 AwtComponent::parentID = env->GetFieldID(cls, "parent", "Ljava/awt/Container;"); 6344 AwtComponent::graphicsConfigID = 6345 env->GetFieldID(cls, "graphicsConfig", "Ljava/awt/GraphicsConfiguration;"); 6346 AwtComponent::focusableID = env->GetFieldID(cls, "focusable", "Z"); 6347 6348 AwtComponent::appContextID = env->GetFieldID(cls, "appContext", 6349 "Lsun/awt/AppContext;"); 6350 6351 AwtComponent::peerGCID = env->GetFieldID(peerCls, "winGraphicsConfig", 6352 "Lsun/awt/Win32GraphicsConfig;"); 6353 6354 AwtComponent::hwndID = env->GetFieldID(peerCls, "hwnd", "J"); 6355 6356 AwtComponent::cursorID = env->GetFieldID(cls, "cursor", "Ljava/awt/Cursor;"); 6357 6358 /* method ids */ 6359 AwtComponent::getFontMID = 6360 env->GetMethodID(cls, "getFont_NoClientCode", "()Ljava/awt/Font;"); 6361 AwtComponent::getToolkitMID = 6362 env->GetMethodID(cls, "getToolkitImpl", "()Ljava/awt/Toolkit;"); 6363 AwtComponent::isEnabledMID = env->GetMethodID(cls, "isEnabledImpl", "()Z"); 6364 AwtComponent::getLocationOnScreenMID = 6365 env->GetMethodID(cls, "getLocationOnScreen_NoTreeLock", "()Ljava/awt/Point;"); 6366 AwtComponent::replaceSurfaceDataMID = 6367 env->GetMethodID(peerCls, "replaceSurfaceData", "()V"); 6368 AwtComponent::replaceSurfaceDataLaterMID = 6369 env->GetMethodID(peerCls, "replaceSurfaceDataLater", "()V"); 6370 AwtComponent::disposeLaterMID = env->GetMethodID(peerCls, "disposeLater", "()V"); 6371 6372 DASSERT(AwtComponent::xID); 6373 DASSERT(AwtComponent::yID); 6374 DASSERT(AwtComponent::heightID); 6375 DASSERT(AwtComponent::widthID); 6376 DASSERT(AwtComponent::visibleID); 6377 DASSERT(AwtComponent::backgroundID); 6378 DASSERT(AwtComponent::foregroundID); 6379 DASSERT(AwtComponent::enabledID); 6380 DASSERT(AwtComponent::parentID); 6381 DASSERT(AwtComponent::hwndID); 6382 6383 DASSERT(AwtComponent::getFontMID); 6384 DASSERT(AwtComponent::getToolkitMID); 6385 DASSERT(AwtComponent::isEnabledMID); 6386 DASSERT(AwtComponent::getLocationOnScreenMID); 6387 DASSERT(AwtComponent::replaceSurfaceDataMID); 6388 DASSERT(AwtComponent::replaceSurfaceDataLaterMID); 6389 DASSERT(AwtComponent::disposeLaterMID); 6390 6391 6392 CATCH_BAD_ALLOC; 6393 } 6394 6395 } /* extern "C" */ 6396 6397 6398 /************************************************************************ 6399 * ComponentPeer native methods 6400 */ 6401 6402 extern "C" { 6403 6404 /* 6405 * Class: sun_awt_windows_WComponentPeer 6406 * Method: pShow 6407 * Signature: ()V 6408 */ 6409 JNIEXPORT void JNICALL 6410 Java_sun_awt_windows_WComponentPeer_pShow(JNIEnv *env, jobject self) 6411 { 6412 TRY; 6413 6414 jobject selfGlobalRef = env->NewGlobalRef(self); 6415 6416 AwtToolkit::GetInstance().SyncCall(AwtComponent::_Show, (void *)selfGlobalRef); 6417 // selfGlobalRef is deleted in _Show 6418 6419 CATCH_BAD_ALLOC; 6420 } 6421 6422 /* 6423 * Class: sun_awt_windows_WComponentPeer 6424 * Method: hide 6425 * Signature: ()V 6426 */ 6427 JNIEXPORT void JNICALL 6428 Java_sun_awt_windows_WComponentPeer_hide(JNIEnv *env, jobject self) 6429 { 6430 TRY; 6431 6432 jobject selfGlobalRef = env->NewGlobalRef(self); 6433 6434 AwtToolkit::GetInstance().SyncCall(AwtComponent::_Hide, (void *)selfGlobalRef); 6435 // selfGlobalRef is deleted in _Hide 6436 6437 CATCH_BAD_ALLOC; 6438 } 6439 6440 /* 6441 * Class: sun_awt_windows_WComponentPeer 6442 * Method: enable 6443 * Signature: ()V 6444 */ 6445 JNIEXPORT void JNICALL 6446 Java_sun_awt_windows_WComponentPeer_enable(JNIEnv *env, jobject self) 6447 { 6448 TRY; 6449 6450 jobject selfGlobalRef = env->NewGlobalRef(self); 6451 6452 AwtToolkit::GetInstance().SyncCall(AwtComponent::_Enable, (void *)selfGlobalRef); 6453 // selfGlobalRef is deleted in _Enable 6454 6455 CATCH_BAD_ALLOC; 6456 } 6457 6458 /* 6459 * Class: sun_awt_windows_WComponentPeer 6460 * Method: disable 6461 * Signature: ()V 6462 */ 6463 JNIEXPORT void JNICALL 6464 Java_sun_awt_windows_WComponentPeer_disable(JNIEnv *env, jobject self) 6465 { 6466 TRY; 6467 6468 jobject selfGlobalRef = env->NewGlobalRef(self); 6469 6470 AwtToolkit::GetInstance().SyncCall(AwtComponent::_Disable, (void *)selfGlobalRef); 6471 // selfGlobalRef is deleted in _Disable 6472 6473 CATCH_BAD_ALLOC; 6474 } 6475 6476 /* 6477 * Class: sun_awt_windows_WComponentPeer 6478 * Method: getLocationOnScreen 6479 * Signature: ()Ljava/awt/Point; 6480 */ 6481 JNIEXPORT jobject JNICALL 6482 Java_sun_awt_windows_WComponentPeer_getLocationOnScreen(JNIEnv *env, jobject self) 6483 { 6484 TRY; 6485 6486 jobject selfGlobalRef = env->NewGlobalRef(self); 6487 6488 jobject resultGlobalRef = (jobject)AwtToolkit::GetInstance().SyncCall( 6489 (void*(*)(void*))AwtComponent::_GetLocationOnScreen, (void *)selfGlobalRef); 6490 // selfGlobalRef is deleted in _GetLocationOnScreen 6491 if (resultGlobalRef != NULL) 6492 { 6493 jobject resultLocalRef = env->NewLocalRef(resultGlobalRef); 6494 env->DeleteGlobalRef(resultGlobalRef); 6495 return resultLocalRef; 6496 } 6497 6498 return NULL; 6499 6500 CATCH_BAD_ALLOC_RET(NULL); 6501 } 6502 6503 /* 6504 * Class: sun_awt_windows_WComponentPeer 6505 * Method: reshape 6506 * Signature: (IIII)V 6507 */ 6508 JNIEXPORT void JNICALL 6509 Java_sun_awt_windows_WComponentPeer_reshape(JNIEnv *env, jobject self, 6510 jint x, jint y, jint w, jint h) 6511 { 6512 TRY; 6513 6514 ReshapeStruct *rs = new ReshapeStruct; 6515 rs->component = env->NewGlobalRef(self); 6516 rs->x = x; 6517 rs->y = y; 6518 rs->w = w; 6519 rs->h = h; 6520 6521 AwtToolkit::GetInstance().SyncCall(AwtComponent::_Reshape, rs); 6522 // global ref and rs are deleted in _Reshape 6523 6524 CATCH_BAD_ALLOC; 6525 } 6526 6527 /* 6528 * Class: sun_awt_windows_WComponentPeer 6529 * Method: reshape 6530 * Signature: (IIII)V 6531 */ 6532 JNIEXPORT void JNICALL 6533 Java_sun_awt_windows_WComponentPeer_reshapeNoCheck(JNIEnv *env, jobject self, 6534 jint x, jint y, jint w, jint h) 6535 { 6536 TRY; 6537 6538 ReshapeStruct *rs = new ReshapeStruct; 6539 rs->component = env->NewGlobalRef(self); 6540 rs->x = x; 6541 rs->y = y; 6542 rs->w = w; 6543 rs->h = h; 6544 6545 AwtToolkit::GetInstance().SyncCall(AwtComponent::_ReshapeNoCheck, rs); 6546 // global ref and rs are deleted in _ReshapeNoCheck 6547 6548 CATCH_BAD_ALLOC; 6549 } 6550 6551 6552 /* 6553 * Class: sun_awt_windows_WComponentPeer 6554 * Method: nativeHandleEvent 6555 * Signature: (Ljava/awt/AWTEvent;)V 6556 */ 6557 JNIEXPORT void JNICALL 6558 Java_sun_awt_windows_WComponentPeer_nativeHandleEvent(JNIEnv *env, 6559 jobject self, 6560 jobject event) 6561 { 6562 TRY; 6563 6564 jobject selfGlobalRef = env->NewGlobalRef(self); 6565 jobject eventGlobalRef = env->NewGlobalRef(event); 6566 6567 NativeHandleEventStruct *nhes = new NativeHandleEventStruct; 6568 nhes->component = selfGlobalRef; 6569 nhes->event = eventGlobalRef; 6570 6571 AwtToolkit::GetInstance().SyncCall(AwtComponent::_NativeHandleEvent, nhes); 6572 // global refs and nhes are deleted in _NativeHandleEvent 6573 6574 CATCH_BAD_ALLOC; 6575 } 6576 6577 /* 6578 * Class: sun_awt_windows_WComponentPeer 6579 * Method: _dispose 6580 * Signature: ()V 6581 */ 6582 JNIEXPORT void JNICALL 6583 Java_sun_awt_windows_WComponentPeer__1dispose(JNIEnv *env, jobject self) 6584 { 6585 TRY_NO_HANG; 6586 6587 AwtObject::_Dispose(self); 6588 6589 CATCH_BAD_ALLOC; 6590 } 6591 6592 /* 6593 * Class: sun_awt_windows_WComponentPeer 6594 * Method: _setForeground 6595 * Signature: (I)V 6596 */ 6597 JNIEXPORT void JNICALL 6598 Java_sun_awt_windows_WComponentPeer__1setForeground(JNIEnv *env, jobject self, 6599 jint rgb) 6600 { 6601 TRY; 6602 6603 jobject selfGlobalRef = env->NewGlobalRef(self); 6604 6605 SetColorStruct *scs = new SetColorStruct; 6606 scs->component = selfGlobalRef; 6607 scs->rgb = rgb; 6608 6609 AwtToolkit::GetInstance().SyncCall(AwtComponent::_SetForeground, scs); 6610 // selfGlobalRef and scs are deleted in _SetForeground() 6611 6612 CATCH_BAD_ALLOC; 6613 } 6614 6615 /* 6616 * Class: sun_awt_windows_WComponentPeer 6617 * Method: _setBackground 6618 * Signature: (I)V 6619 */ 6620 JNIEXPORT void JNICALL 6621 Java_sun_awt_windows_WComponentPeer__1setBackground(JNIEnv *env, jobject self, 6622 jint rgb) 6623 { 6624 TRY; 6625 6626 jobject selfGlobalRef = env->NewGlobalRef(self); 6627 6628 SetColorStruct *scs = new SetColorStruct; 6629 scs->component = selfGlobalRef; 6630 scs->rgb = rgb; 6631 6632 AwtToolkit::GetInstance().SyncCall(AwtComponent::_SetBackground, scs); 6633 // selfGlobalRef and scs are deleted in _SetBackground() 6634 6635 CATCH_BAD_ALLOC; 6636 } 6637 6638 /* 6639 * Class: sun_awt_windows_WComponentPeer 6640 * Method: _setFont 6641 * Signature: (Ljava/awt/Font;)V 6642 */ 6643 JNIEXPORT void JNICALL 6644 Java_sun_awt_windows_WComponentPeer__1setFont(JNIEnv *env, jobject self, 6645 jobject font) 6646 { 6647 TRY; 6648 6649 jobject selfGlobalRef = env->NewGlobalRef(self); 6650 jobject fontGlobalRef = env->NewGlobalRef(font); 6651 6652 SetFontStruct *sfs = new SetFontStruct; 6653 sfs->component = selfGlobalRef; 6654 sfs->font = fontGlobalRef; 6655 6656 AwtToolkit::GetInstance().SyncCall(AwtComponent::_SetFont, sfs); 6657 // global refs and sfs are deleted in _SetFont() 6658 6659 CATCH_BAD_ALLOC; 6660 } 6661 6662 /* 6663 * Class: sun_awt_windows_WComponentPeer 6664 * Method: focusGained 6665 * Signature: (Z) 6666 */ 6667 JNIEXPORT void JNICALL Java_sun_awt_windows_WComponentPeer_setFocus 6668 (JNIEnv *env, jobject self, jboolean doSetFocus) 6669 { 6670 TRY; 6671 6672 jobject selfGlobalRef = env->NewGlobalRef(self); 6673 6674 SetFocusStruct *sfs = new SetFocusStruct; 6675 sfs->component = selfGlobalRef; 6676 sfs->doSetFocus = doSetFocus; 6677 6678 AwtToolkit::GetInstance().SyncCall( 6679 (void*(*)(void*))AwtComponent::_SetFocus, sfs); 6680 // global refs and self are deleted in _SetFocus 6681 6682 CATCH_BAD_ALLOC; 6683 } 6684 6685 /* 6686 * Class: sun_awt_windows_WComponentPeer 6687 * Method: start 6688 * Signature: ()V 6689 */ 6690 JNIEXPORT void JNICALL 6691 Java_sun_awt_windows_WComponentPeer_start(JNIEnv *env, jobject self) 6692 { 6693 TRY; 6694 6695 jobject selfGlobalRef = env->NewGlobalRef(self); 6696 6697 AwtToolkit::GetInstance().SyncCall(AwtComponent::_Start, (void *)selfGlobalRef); 6698 // selfGlobalRef is deleted in _Start 6699 6700 CATCH_BAD_ALLOC; 6701 } 6702 6703 /* 6704 * Class: sun_awt_windows_WComponentPeer 6705 * Method: beginValidate 6706 * Signature: ()V 6707 */ 6708 JNIEXPORT void JNICALL 6709 Java_sun_awt_windows_WComponentPeer_beginValidate(JNIEnv *env, jobject self) 6710 { 6711 TRY; 6712 6713 jobject selfGlobalRef = env->NewGlobalRef(self); 6714 6715 AwtToolkit::GetInstance().SyncCall(AwtComponent::_BeginValidate, (void *)selfGlobalRef); 6716 // selfGlobalRef is deleted in _BeginValidate 6717 6718 CATCH_BAD_ALLOC; 6719 } 6720 6721 /* 6722 * Class: sun_awt_windows_WComponentPeer 6723 * Method: endValidate 6724 * Signature: ()V 6725 */ 6726 JNIEXPORT void JNICALL 6727 Java_sun_awt_windows_WComponentPeer_endValidate(JNIEnv *env, jobject self) 6728 { 6729 TRY; 6730 6731 jobject selfGlobalRef = env->NewGlobalRef(self); 6732 6733 AwtToolkit::GetInstance().SyncCall(AwtComponent::_EndValidate, (void *)selfGlobalRef); 6734 // selfGlobalRef is deleted in _EndValidate 6735 6736 CATCH_BAD_ALLOC; 6737 } 6738 6739 JNIEXPORT void JNICALL 6740 Java_sun_awt_windows_WComponentPeer_updateWindow(JNIEnv *env, jobject self) 6741 { 6742 TRY; 6743 6744 jobject selfGlobalRef = env->NewGlobalRef(self); 6745 6746 AwtToolkit::GetInstance().SyncCall(AwtComponent::_UpdateWindow, (void *)selfGlobalRef); 6747 // selfGlobalRef is deleted in _UpdateWindow 6748 6749 CATCH_BAD_ALLOC; 6750 } 6751 6752 /* 6753 * Class: sun_awt_windows_WComponentPeer 6754 * Method: addNativeDropTarget 6755 * Signature: ()L 6756 */ 6757 6758 JNIEXPORT jlong JNICALL 6759 Java_sun_awt_windows_WComponentPeer_addNativeDropTarget(JNIEnv *env, 6760 jobject self) 6761 { 6762 TRY; 6763 6764 jobject selfGlobalRef = env->NewGlobalRef(self); 6765 6766 return ptr_to_jlong(AwtToolkit::GetInstance().SyncCall( 6767 (void*(*)(void*))AwtComponent::_AddNativeDropTarget, 6768 (void *)selfGlobalRef)); 6769 // selfGlobalRef is deleted in _AddNativeDropTarget 6770 6771 CATCH_BAD_ALLOC_RET(0); 6772 } 6773 6774 /* 6775 * Class: sun_awt_windows_WComponentPeer 6776 * Method: removeNativeDropTarget 6777 * Signature: ()V 6778 */ 6779 6780 JNIEXPORT void JNICALL 6781 Java_sun_awt_windows_WComponentPeer_removeNativeDropTarget(JNIEnv *env, 6782 jobject self) 6783 { 6784 TRY; 6785 6786 jobject selfGlobalRef = env->NewGlobalRef(self); 6787 6788 AwtToolkit::GetInstance().SyncCall( 6789 AwtComponent::_RemoveNativeDropTarget, (void *)selfGlobalRef); 6790 // selfGlobalRef is deleted in _RemoveNativeDropTarget 6791 6792 CATCH_BAD_ALLOC; 6793 } 6794 6795 /* 6796 * Class: sun_awt_windows_WComponentPeer 6797 * Method: getTargetGC 6798 * Signature: ()Ljava/awt/GraphicsConfiguration; 6799 */ 6800 JNIEXPORT jobject JNICALL 6801 Java_sun_awt_windows_WComponentPeer_getTargetGC(JNIEnv* env, jobject theThis) 6802 { 6803 TRY; 6804 6805 jobject targetObj; 6806 jobject gc = 0; 6807 6808 targetObj = env->GetObjectField(theThis, AwtObject::targetID); 6809 DASSERT(targetObj); 6810 6811 gc = env->GetObjectField(targetObj, AwtComponent::graphicsConfigID); 6812 return gc; 6813 6814 CATCH_BAD_ALLOC_RET(NULL); 6815 } 6816 6817 /* 6818 * Class: sun_awt_windows_WComponentPeer 6819 * Method: createPrintedPixels 6820 * Signature: (IIIIII)I[ 6821 */ 6822 JNIEXPORT jintArray JNICALL 6823 Java_sun_awt_windows_WComponentPeer_createPrintedPixels(JNIEnv* env, 6824 jobject self, jint srcX, jint srcY, jint srcW, jint srcH, jint alpha) 6825 { 6826 TRY; 6827 6828 jobject selfGlobalRef = env->NewGlobalRef(self); 6829 6830 CreatePrintedPixelsStruct *cpps = new CreatePrintedPixelsStruct; 6831 cpps->component = selfGlobalRef; 6832 cpps->srcx = srcX; 6833 cpps->srcy = srcY; 6834 cpps->srcw = srcW; 6835 cpps->srch = srcH; 6836 cpps->alpha = alpha; 6837 6838 jintArray globalRef = (jintArray)AwtToolkit::GetInstance().SyncCall( 6839 (void*(*)(void*))AwtComponent::_CreatePrintedPixels, cpps); 6840 // selfGlobalRef and cpps are deleted in _CreatePrintedPixels 6841 if (globalRef != NULL) 6842 { 6843 jintArray localRef = (jintArray)env->NewLocalRef(globalRef); 6844 env->DeleteGlobalRef(globalRef); 6845 return localRef; 6846 } 6847 else 6848 { 6849 return NULL; 6850 } 6851 6852 CATCH_BAD_ALLOC_RET(NULL); 6853 } 6854 6855 /* 6856 * Class: sun_awt_windows_WComponentPeer 6857 * Method: nativeHandlesWheelScrolling 6858 * Signature: ()Z 6859 */ 6860 JNIEXPORT jboolean JNICALL 6861 Java_sun_awt_windows_WComponentPeer_nativeHandlesWheelScrolling (JNIEnv* env, 6862 jobject self) 6863 { 6864 TRY; 6865 6866 return (jboolean)AwtToolkit::GetInstance().SyncCall( 6867 (void *(*)(void *))AwtComponent::_NativeHandlesWheelScrolling, 6868 env->NewGlobalRef(self)); 6869 // global ref is deleted in _NativeHandlesWheelScrolling 6870 6871 CATCH_BAD_ALLOC_RET(NULL); 6872 } 6873 6874 /* 6875 * Class: sun_awt_windows_WComponentPeer 6876 * Method: isObscured 6877 * Signature: ()Z 6878 */ 6879 JNIEXPORT jboolean JNICALL 6880 Java_sun_awt_windows_WComponentPeer_isObscured(JNIEnv* env, 6881 jobject self) 6882 { 6883 TRY; 6884 6885 jobject selfGlobalRef = env->NewGlobalRef(self); 6886 6887 return (jboolean)AwtToolkit::GetInstance().SyncCall( 6888 (void*(*)(void*))AwtComponent::_IsObscured, 6889 (void *)selfGlobalRef); 6890 // selfGlobalRef is deleted in _IsObscured 6891 6892 CATCH_BAD_ALLOC_RET(NULL); 6893 } 6894 6895 JNIEXPORT void JNICALL 6896 Java_sun_awt_windows_WComponentPeer_pSetParent(JNIEnv* env, jobject self, jobject parent) { 6897 TRY; 6898 6899 typedef AwtComponent* PComponent; 6900 AwtComponent** comps = new PComponent[2]; 6901 AwtComponent* comp = (AwtComponent*)JNI_GET_PDATA(self); 6902 AwtComponent* parentComp = (AwtComponent*)JNI_GET_PDATA(parent); 6903 comps[0] = comp; 6904 comps[1] = parentComp; 6905 6906 AwtToolkit::GetInstance().SyncCall(AwtComponent::SetParent, comps); 6907 // comps is deleted in SetParent 6908 6909 CATCH_BAD_ALLOC; 6910 } 6911 6912 JNIEXPORT void JNICALL 6913 Java_sun_awt_windows_WComponentPeer_setRectangularShape(JNIEnv* env, jobject self, 6914 jint x1, jint y1, jint x2, jint y2, jobject region) 6915 { 6916 TRY; 6917 6918 SetRectangularShapeStruct * data = new SetRectangularShapeStruct; 6919 data->component = env->NewGlobalRef(self); 6920 data->x1 = x1; 6921 data->x2 = x2; 6922 data->y1 = y1; 6923 data->y2 = y2; 6924 if (region) { 6925 data->region = env->NewGlobalRef(region); 6926 } else { 6927 data->region = NULL; 6928 } 6929 6930 AwtToolkit::GetInstance().SyncCall(AwtComponent::_SetRectangularShape, data); 6931 // global refs and data are deleted in _SetRectangularShape 6932 6933 CATCH_BAD_ALLOC; 6934 } 6935 6936 JNIEXPORT void JNICALL 6937 Java_sun_awt_windows_WComponentPeer_setZOrder(JNIEnv* env, jobject self, jlong above) 6938 { 6939 TRY; 6940 6941 SetZOrderStruct * data = new SetZOrderStruct; 6942 data->component = env->NewGlobalRef(self); 6943 data->above = above; 6944 6945 AwtToolkit::GetInstance().SyncCall(AwtComponent::_SetZOrder, data); 6946 // global refs and data are deleted in _SetLower 6947 6948 CATCH_BAD_ALLOC; 6949 } 6950 6951 } /* extern "C" */ 6952 6953 6954 /************************************************************************ 6955 * Diagnostic routines 6956 */ 6957 6958 #ifdef DEBUG 6959 6960 void AwtComponent::VerifyState() 6961 { 6962 if (AwtToolkit::GetInstance().VerifyComponents() == FALSE) { 6963 return; 6964 } 6965 6966 if (m_callbacksEnabled == FALSE) { 6967 /* Component is not fully setup yet. */ 6968 return; 6969 } 6970 6971 /* Get target bounds. */ 6972 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); 6973 if (env->PushLocalFrame(10) < 0) 6974 return; 6975 6976 jobject target = GetTarget(env); 6977 6978 jint x = env->GetIntField(target, AwtComponent::xID); 6979 jint y = env->GetIntField(target, AwtComponent::yID); 6980 jint width = env->GetIntField(target, AwtComponent::widthID); 6981 jint height = env->GetIntField(target, AwtComponent::heightID); 6982 6983 /* Convert target origin to absolute coordinates */ 6984 while (TRUE) { 6985 6986 jobject parent = env->GetObjectField(target, AwtComponent::parentID); 6987 if (parent == NULL) { 6988 break; 6989 } 6990 x += env->GetIntField(parent, AwtComponent::xID); 6991 y += env->GetIntField(parent, AwtComponent::yID); 6992 6993 /* If this component has insets, factor them in, but ignore 6994 * top-level windows. 6995 */ 6996 jobject parent2 = env->GetObjectField(parent, AwtComponent::parentID); 6997 if (parent2 != NULL) { 6998 jobject peer = GetPeerForTarget(env, parent); 6999 if (peer != NULL && 7000 JNU_IsInstanceOfByName(env, peer, 7001 "sun/awt/windows/WPanelPeer") > 0) { 7002 jobject insets = 7003 JNU_CallMethodByName(env, NULL, peer,"insets", 7004 "()Ljava/awt/Insets;").l; 7005 x += (env)->GetIntField(insets, AwtInsets::leftID); 7006 y += (env)->GetIntField(insets, AwtInsets::topID); 7007 } 7008 } 7009 env->DeleteLocalRef(target); 7010 target = parent; 7011 } 7012 7013 // Test whether component's bounds match the native window's 7014 RECT rect; 7015 VERIFY(::GetWindowRect(GetHWnd(), &rect)); 7016 #if 0 7017 DASSERT( (x == rect.left) && 7018 (y == rect.top) && 7019 (width == (rect.right-rect.left)) && 7020 (height == (rect.bottom-rect.top)) ); 7021 #else 7022 BOOL fSizeValid = ( (x == rect.left) && 7023 (y == rect.top) && 7024 (width == (rect.right-rect.left)) && 7025 (height == (rect.bottom-rect.top)) ); 7026 #endif 7027 7028 // See if visible state matches 7029 BOOL wndVisible = ::IsWindowVisible(GetHWnd()); 7030 jboolean targetVisible; 7031 // To avoid possibly running client code on the toolkit thread, don't 7032 // do the following check if we're running on the toolkit thread. 7033 if (AwtToolkit::MainThread() != ::GetCurrentThreadId()) { 7034 targetVisible = JNU_CallMethodByName(env, NULL, GetTarget(env), 7035 "isShowing", "()Z").z; 7036 DASSERT(!safe_ExceptionOccurred(env)); 7037 } else { 7038 targetVisible = wndVisible ? 1 : 0; 7039 } 7040 #if 0 7041 DASSERT( (targetVisible && wndVisible) || 7042 (!targetVisible && !wndVisible) ); 7043 #else 7044 BOOL fVisibleValid = ( (targetVisible && wndVisible) || 7045 (!targetVisible && !wndVisible) ); 7046 #endif 7047 7048 // Check enabled state 7049 BOOL wndEnabled = ::IsWindowEnabled(GetHWnd()); 7050 jboolean enabled = (jboolean)env->GetBooleanField(target, 7051 AwtComponent::enabledID); 7052 #if 0 7053 DASSERT( (enabled && wndEnabled) || 7054 (!enabled && !wndEnabled) ); 7055 #else 7056 BOOL fEnabledValid = ((enabled && wndEnabled) || 7057 (!(enabled && !wndEnabled) )); 7058 7059 if (!fSizeValid || !fVisibleValid || !fEnabledValid) { 7060 printf("AwtComponent::ValidateState() failed:\n"); 7061 // To avoid possibly running client code on the toolkit thread, don't 7062 // do the following call if we're running on the toolkit thread. 7063 if (AwtToolkit::MainThread() != ::GetCurrentThreadId()) { 7064 jstring targetStr = 7065 (jstring)JNU_CallMethodByName(env, NULL, GetTarget(env), 7066 "getName", 7067 "()Ljava/lang/String;").l; 7068 DASSERT(!safe_ExceptionOccurred(env)); 7069 LPCWSTR targetStrW = JNU_GetStringPlatformChars(env, targetStr, NULL); 7070 printf("\t%S\n", targetStrW); 7071 JNU_ReleaseStringPlatformChars(env, targetStr, targetStrW); 7072 } 7073 printf("\twas: [%d,%d,%dx%d]\n", x, y, width, height); 7074 if (!fSizeValid) { 7075 printf("\tshould be: [%d,%d,%dx%d]\n", rect.left, rect.top, 7076 rect.right-rect.left, rect.bottom-rect.top); 7077 } 7078 if (!fVisibleValid) { 7079 printf("\tshould be: %s\n", 7080 (targetVisible) ? "visible" : "hidden"); 7081 } 7082 if (!fEnabledValid) { 7083 printf("\tshould be: %s\n", 7084 enabled ? "enabled" : "disabled"); 7085 } 7086 } 7087 #endif 7088 env->PopLocalFrame(0); 7089 } 7090 #endif //DEBUG 7091 7092 // Methods for globally managed DC list 7093 7094 /** 7095 * Add a new DC to the DC list for this component. 7096 */ 7097 void DCList::AddDC(HDC hDC, HWND hWnd) 7098 { 7099 DCItem *newItem = new DCItem; 7100 newItem->hDC = hDC; 7101 newItem->hWnd = hWnd; 7102 AddDCItem(newItem); 7103 } 7104 7105 void DCList::AddDCItem(DCItem *newItem) 7106 { 7107 listLock.Enter(); 7108 newItem->next = head; 7109 head = newItem; 7110 listLock.Leave(); 7111 } 7112 7113 /** 7114 * Given a DC, remove it from the DC list and return 7115 * TRUE if it exists on the current list. Otherwise 7116 * return FALSE. 7117 * A DC may not exist on the list because it has already 7118 * been released elsewhere (for example, the window 7119 * destruction process may release a DC while a rendering 7120 * thread may also want to release a DC when it notices that 7121 * its DC is obsolete for the current window). 7122 */ 7123 DCItem *DCList::RemoveDC(HDC hDC) 7124 { 7125 listLock.Enter(); 7126 DCItem **prevPtrPtr = &head; 7127 DCItem *listPtr = head; 7128 while (listPtr) { 7129 DCItem *nextPtr = listPtr->next; 7130 if (listPtr->hDC == hDC) { 7131 *prevPtrPtr = nextPtr; 7132 break; 7133 } 7134 prevPtrPtr = &listPtr->next; 7135 listPtr = nextPtr; 7136 } 7137 listLock.Leave(); 7138 return listPtr; 7139 } 7140 7141 /** 7142 * Remove all DCs from the DC list which are associated with 7143 * the same window as hWnd. Return the list of those 7144 * DC's to the caller (which will then probably want to 7145 * call ReleaseDC() for the returned DCs). 7146 */ 7147 DCItem *DCList::RemoveAllDCs(HWND hWnd) 7148 { 7149 listLock.Enter(); 7150 DCItem **prevPtrPtr = &head; 7151 DCItem *listPtr = head; 7152 DCItem *newListPtr = NULL; 7153 BOOL ret = FALSE; 7154 while (listPtr) { 7155 DCItem *nextPtr = listPtr->next; 7156 if (listPtr->hWnd == hWnd) { 7157 *prevPtrPtr = nextPtr; 7158 listPtr->next = newListPtr; 7159 newListPtr = listPtr; 7160 } else { 7161 prevPtrPtr = &listPtr->next; 7162 } 7163 listPtr = nextPtr; 7164 } 7165 listLock.Leave(); 7166 return newListPtr; 7167 } 7168 7169 7170 /** 7171 * Realize palettes of all existing HDC objects 7172 */ 7173 void DCList::RealizePalettes(int screen) 7174 { 7175 listLock.Enter(); 7176 DCItem *listPtr = head; 7177 while (listPtr) { 7178 AwtWin32GraphicsDevice::RealizePalette(listPtr->hDC, screen); 7179 listPtr = listPtr->next; 7180 } 7181 listLock.Leave(); 7182 } 7183 7184 void MoveDCToPassiveList(HDC hDC) { 7185 DCItem *removedDC; 7186 if ((removedDC = activeDCList.RemoveDC(hDC)) != NULL) { 7187 passiveDCList.AddDCItem(removedDC); 7188 } 7189 } 7190 7191 void ReleaseDCList(HWND hwnd, DCList &list) { 7192 DCItem *removedDCs = list.RemoveAllDCs(hwnd); 7193 while (removedDCs) { 7194 DCItem *tmpDCList = removedDCs; 7195 DASSERT(::GetObjectType(tmpDCList->hDC) == OBJ_DC); 7196 int retValue = ::ReleaseDC(tmpDCList->hWnd, tmpDCList->hDC); 7197 VERIFY(retValue != 0); 7198 if (retValue != 0) { 7199 // Valid ReleaseDC call; need to decrement GDI object counter 7200 AwtGDIObject::Decrement(); 7201 } 7202 removedDCs = removedDCs->next; 7203 delete tmpDCList; 7204 } 7205 } 7206