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