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