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