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