1 /* 2 * Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 #include "common.h" 27 28 #include "FullScreenWindow.h" 29 #include "GlassApplication.h" 30 #include "GlassWindow.h" 31 #include "GlassScreen.h" 32 #include "GlassMenu.h" 33 #include "GlassView.h" 34 #include "GlassDnD.h" 35 #include "Pixels.h" 36 #include "GlassCursor.h" 37 #include "GlassScreen.h" 38 39 #include "com_sun_glass_events_WindowEvent.h" 40 #include "com_sun_glass_ui_Window.h" 41 #include "com_sun_glass_ui_Window_Level.h" 42 #include "com_sun_glass_ui_win_WinWindow.h" 43 44 45 // Helper LEAVE_MAIN_THREAD for GlassWindow 46 #define LEAVE_MAIN_THREAD_WITH_hWnd \ 47 HWND hWnd; \ 48 LEAVE_MAIN_THREAD; \ 49 ARG(hWnd) = (HWND)ptr; 50 51 static LPCTSTR szGlassWindowClassName = TEXT("GlassWindowClass"); 52 53 static jmethodID midNotifyClose; 54 static jmethodID midNotifyMove; 55 static jmethodID midNotifyResize; 56 static jmethodID midNotifyScaleChanged; 57 static jmethodID midNotifyMoveToAnotherScreen; 58 59 unsigned int GlassWindow::sm_instanceCounter = 0; 60 HHOOK GlassWindow::sm_hCBTFilter = NULL; 61 HWND GlassWindow::sm_grabWindow = NULL; 62 63 GlassWindow::GlassWindow(jobject jrefThis, bool isTransparent, bool isDecorated, bool isUnified, bool isChild, HWND parentOrOwner) 64 : BaseWnd(parentOrOwner), 65 ViewContainer(), 66 m_state(Normal), 67 m_isFocusable(true), 68 m_isFocused(false), 69 m_focusEvent(0), 70 m_isResizable(true), 71 m_isTransparent(isTransparent), 72 m_isDecorated(isDecorated), 73 m_isUnified(isUnified), 74 m_hMenu(NULL), 75 m_alpha(255), 76 m_isEnabled(true), 77 m_parent(isChild ? parentOrOwner : NULL), 78 m_delegateWindow(NULL), 79 m_isInFullScreen(false), 80 m_beforeFullScreenStyle(0), 81 m_beforeFullScreenExStyle(0), 82 m_beforeFullScreenMenu(NULL), 83 m_hIcon(NULL) 84 { 85 m_grefThis = GetEnv()->NewGlobalRef(jrefThis); 86 m_minSize.x = m_minSize.y = -1; // "not set" value 87 m_maxSize.x = m_maxSize.y = -1; // "not set" value 88 m_hMonitor = NULL; 89 m_insets.left = m_insets.top = m_insets.right = m_insets.bottom = 0; 90 m_beforeFullScreenRect.left = m_beforeFullScreenRect.top = 91 m_beforeFullScreenRect.right = m_beforeFullScreenRect.bottom = 0; 92 93 if (++GlassWindow::sm_instanceCounter == 1) { 94 GlassWindow::sm_hCBTFilter = 95 ::SetWindowsHookEx(WH_CBT, 96 (HOOKPROC)GlassWindow::CBTFilter, 97 0, GlassApplication::GetMainThreadId()); 98 } 99 if (isChild) { 100 GlassApplication::InstallMouseLLHook(); 101 } 102 } 103 104 GlassWindow::~GlassWindow() 105 { 106 if (m_hIcon) { 107 ::DestroyIcon(m_hIcon); 108 } 109 110 if (m_grefThis) { 111 GetEnv()->DeleteGlobalRef(m_grefThis); 112 } 113 114 if (IsChild()) { 115 GlassApplication::UninstallMouseLLHook(); 116 } 117 118 if (--GlassWindow::sm_instanceCounter == 0) { 119 ::UnhookWindowsHookEx(GlassWindow::sm_hCBTFilter); 120 } 121 } 122 123 LPCTSTR GlassWindow::GetWindowClassNameSuffix() 124 { 125 return szGlassWindowClassName; 126 } 127 128 HWND GlassWindow::Create(DWORD dwStyle, DWORD dwExStyle, HMONITOR hMonitor, HWND owner) 129 { 130 m_hMonitor = hMonitor; 131 132 int x = CW_USEDEFAULT; 133 int y = CW_USEDEFAULT; 134 int w = CW_USEDEFAULT; 135 int h = CW_USEDEFAULT; 136 if ((dwStyle & WS_POPUP) != 0) { 137 // CW_USEDEFAULT doesn't work for WS_POPUP windows 138 RECT r; 139 if (BaseWnd::GetDefaultWindowBounds(&r)) { 140 x = r.left; 141 y = r.top; 142 w = r.right - r.left; 143 h = r.bottom - r.top; 144 } 145 } 146 147 HWND hwnd = BaseWnd::Create(owner, x, y, w, h, 148 TEXT(""), dwExStyle, dwStyle, NULL); 149 150 ViewContainer::InitDropTarget(hwnd); 151 ViewContainer::InitManipProcessor(hwnd); 152 153 return hwnd; 154 } 155 156 void GlassWindow::Close() 157 { 158 UngrabFocus(); 159 ViewContainer::ReleaseDropTarget(); 160 ViewContainer::ReleaseManipProcessor(); 161 } 162 163 void GlassWindow::setMinSize(long width, long height) 164 { 165 m_minSize.x = width; 166 m_minSize.y = height; 167 } 168 169 void GlassWindow::setMaxSize(long width, long height) 170 { 171 m_maxSize.x = width; 172 m_maxSize.y = height; 173 } 174 175 void GlassWindow::updateMinMaxSize(RECT &windowRect) 176 { 177 if (m_minSize.x >= 0) { 178 // min size has been set 179 if (windowRect.right - windowRect.left < m_minSize.x) { 180 windowRect.right = windowRect.left + m_minSize.x; 181 } 182 if (windowRect.bottom - windowRect.top < m_minSize.y) { 183 windowRect.bottom = windowRect.top + m_minSize.y; 184 } 185 } 186 if (m_maxSize.x >= 0) { 187 // max size has been set 188 if (windowRect.right - windowRect.left > m_maxSize.x) { 189 windowRect.right = windowRect.left + m_maxSize.x; 190 } 191 if (windowRect.bottom - windowRect.top > m_maxSize.y) { 192 windowRect.bottom = windowRect.top + m_maxSize.y; 193 } 194 } 195 196 } 197 198 void GlassWindow::SetFocusable(bool isFocusable) 199 { 200 m_isFocusable = isFocusable; 201 202 LONG exStyle = ::GetWindowLong(GetHWND(), GWL_EXSTYLE); 203 if (!isFocusable) { 204 //NOTE: this style works 'by itself' when there's only one window 205 // in this application. It does prevent the window from activation 206 // then. However, as soon as there is another window, we also need 207 // to handle WM_MOUSEACTIVATE and use the CBTFilter() hook. 208 // The useful part of the style: it removes the window from the 209 // task bar (and the Alt-Tab list). 210 ::SetWindowLong(GetHWND(), GWL_EXSTYLE, exStyle | WS_EX_NOACTIVATE); 211 212 if (::GetFocus() == GetHWND()) { 213 // We can't resign activation, but at least we can reset the focus 214 ::SetFocus(NULL); 215 } 216 } else { 217 ::SetWindowLong(GetHWND(), GWL_EXSTYLE, exStyle & ~WS_EX_NOACTIVATE); 218 } 219 } 220 221 LRESULT CALLBACK GlassWindow::CBTFilter(int nCode, WPARAM wParam, LPARAM lParam) 222 { 223 if (nCode == HCBT_ACTIVATE || nCode == HCBT_SETFOCUS) { 224 BaseWnd *pWindow = BaseWnd::FromHandle((HWND)wParam); 225 if (pWindow && pWindow->IsGlassWindow()) { 226 GlassWindow * window = (GlassWindow*)pWindow; 227 228 if (!window->IsEnabled()) { 229 window->HandleFocusDisabledEvent(); 230 return 1; 231 } 232 if (!window->IsFocusable()) { 233 return 1; 234 } 235 } 236 } 237 return ::CallNextHookEx(GlassWindow::sm_hCBTFilter, nCode, wParam, lParam); 238 } 239 240 #ifndef WM_DPICHANGED 241 #define WM_DPICHANGED 0x02E0 242 #endif 243 244 char *StringForMsg(UINT msg) { 245 switch (msg) { 246 case WM_DPICHANGED: return "WM_DPICHANGED"; 247 case WM_ERASEBKGND: return "WM_ERASEBKGND"; 248 case WM_WINDOWPOSCHANGING: return "WM_WINDOWPOSCHANGING"; 249 case WM_NCPAINT: return "WM_NCPAINT"; 250 case WM_SETCURSOR: return "WM_SETCURSOR"; 251 case WM_NCMOUSEMOVE: return "WM_NCMOUSEMOVE"; 252 case WM_NCHITTEST: return "WM_NCHITTEST"; 253 case WM_NCMOUSELEAVE: return "WM_NCMOUSELEAVE"; 254 case WM_EXITSIZEMOVE: return "WM_EXITSIZEMOVE"; 255 case WM_CREATE: return "WM_CREATE"; 256 case WM_NCDESTROY: return "WM_NCDESTROY"; 257 case WM_STYLECHANGED: return "WM_STYLECHANGED"; 258 case WM_STYLECHANGING: return "WM_STYLECHANGING"; 259 case WM_GETICON: return "WM_GETICON"; 260 case WM_SETICON: return "WM_SETICON"; 261 case WM_ACTIVATEAPP: return "WM_ACTIVATEAPP"; 262 case WM_NCACTIVATE: return "WM_NCACTIVATE"; 263 case WM_IME_SETCONTEXT: return "WM_IME_SETCONTEXT"; 264 case WM_SETTEXT: return "WM_SETTEXT"; 265 case WM_DWMNCRENDERINGCHANGED: return "WM_DWMNCRENDERINGCHANGED"; 266 case WM_SYSCOMMAND: return "WM_SYSCOMMAND"; 267 268 case WM_SHOWWINDOW: return "WM_SHOWWINDOW"; 269 case WM_DWMCOMPOSITIONCHANGED: return "WM_DWMCOMPOSITIONCHANGED"; 270 case WM_SIZE: return "WM_SIZE"; 271 case WM_MOVING: return "WM_MOVING"; 272 case WM_MOVE: return "WM_MOVE"; 273 case WM_WINDOWPOSCHANGED: return "WM_WINDOWPOSCHANGED"; 274 case WM_CLOSE: return "WM_CLOSE"; 275 case WM_DESTROY: return "WM_DESTROY"; 276 case WM_ACTIVATE: return "WM_ACTIVATE"; 277 case WM_MOUSEACTIVATE: return "WM_MOUSEACTIVATE"; 278 case WM_SETFOCUS: return "WM_SETFOCUS"; 279 case WM_KILLFOCUS: return "WM_KILLFOCUS"; 280 case WM_GETMINMAXINFO: return "WM_GETMINMAXINFO"; 281 case WM_COMMAND: return "WM_COMMAND"; 282 case WM_INPUTLANGCHANGE: return "WM_INPUTLANGCHANGE"; 283 case WM_NCCALCSIZE: return "WM_NCCALCSIZE"; 284 case WM_PAINT: return "WM_PAINT"; 285 case WM_CONTEXTMENU: return "WM_CONTEXTMENU"; 286 case WM_LBUTTONDOWN: return "WM_LBUTTONDOWN"; 287 case WM_RBUTTONDOWN: return "WM_RBUTTONDOWN"; 288 case WM_MBUTTONDOWN: return "WM_MBUTTONDOWN"; 289 case WM_LBUTTONUP: return "WM_LBUTTONUP"; 290 case WM_LBUTTONDBLCLK: return "WM_LBUTTONDBLCLK"; 291 case WM_RBUTTONUP: return "WM_RBUTTONUP"; 292 case WM_RBUTTONDBLCLK: return "WM_RBUTTONDBLCLK"; 293 case WM_MBUTTONUP: return "WM_MBUTTONUP"; 294 case WM_MBUTTONDBLCLK: return "WM_MBUTTONDBLCLK"; 295 case WM_MOUSEWHEEL: return "WM_MOUSEWHEEL"; 296 case WM_MOUSEHWHEEL: return "WM_MOUSEHWHEEL"; 297 case WM_MOUSELEAVE: return "WM_MOUSELEAVE"; 298 case WM_MOUSEMOVE: return "WM_MOUSEMOVE"; 299 case WM_CAPTURECHANGED: return "WM_CAPTURECHANGED"; 300 case WM_SYSKEYDOWN: return "WM_SYSKEYDOWN"; 301 case WM_SYSKEYUP: return "WM_SYSKEYUP"; 302 case WM_KEYDOWN: return "WM_KEYDOWN"; 303 case WM_KEYUP: return "WM_KEYUP"; 304 case WM_DEADCHAR: return "WM_DEADCHAR"; 305 case WM_CHAR: return "WM_CHAR"; 306 case WM_IME_CHAR: return "WM_IME_CHAR"; 307 case WM_IME_COMPOSITION: return "WM_IME_COMPOSITION"; 308 case WM_IME_ENDCOMPOSITION: return "WM_IME_ENDCOMPOSITION"; 309 case WM_IME_NOTIFY: return "WM_IME_NOTIFY"; 310 case WM_IME_STARTCOMPOSITION: return "WM_IME_STARTCOMPOSITION"; 311 case WM_NCLBUTTONDOWN: return "WM_NCLBUTTONDOWN"; 312 case WM_NCMBUTTONDOWN: return "WM_NCMBUTTONDOWN"; 313 case WM_NCRBUTTONDOWN: return "WM_NCRBUTTONDOWN"; 314 case WM_NCXBUTTONDOWN: return "WM_NCXBUTTONDOWN"; 315 case WM_TOUCH: return "WM_TOUCH"; 316 case WM_TIMER: return "WM_TIMER"; 317 case WM_GETOBJECT: return "WM_GETOBJECT"; 318 } 319 return "Unknown"; 320 } 321 322 LRESULT GlassWindow::WindowProc(UINT msg, WPARAM wParam, LPARAM lParam) 323 { 324 // fprintf(stderr, "msg = 0x%04x (%s)\n", msg, StringForMsg(msg)); 325 MessageResult commonResult = BaseWnd::CommonWindowProc(msg, wParam, lParam); 326 if (commonResult.processed) { 327 // fprintf(stderr, " (handled by CommonWindowProc)\n"); 328 return commonResult.result; 329 } 330 331 switch (msg) { 332 case WM_SHOWWINDOW: 333 // It's possible that move/size events are reported by the platform 334 // before the peer listener is set. As a result, location/size are 335 // not reported, so resending them from here. 336 HandleMoveEvent(NULL); 337 HandleSizeEvent(com_sun_glass_events_WindowEvent_RESIZE, NULL); 338 // The call below may be restricted to WS_POPUP windows 339 NotifyViewSize(GetHWND()); 340 341 if (!wParam) { 342 ResetMouseTracking(GetHWND()); 343 } 344 if (IS_WINVISTA) { 345 ::SendMessage(GetHWND(), WM_DWMCOMPOSITIONCHANGED, 0, 0); 346 } 347 break; 348 case WM_DWMCOMPOSITIONCHANGED: 349 if (m_isUnified && (IS_WINVISTA)) { 350 BOOL bEnabled = FALSE; 351 if(SUCCEEDED(::DwmIsCompositionEnabled(&bEnabled)) && bEnabled) { 352 MARGINS dwmMargins = { -1, -1, -1, -1 }; 353 ::DwmExtendFrameIntoClientArea(GetHWND(), &dwmMargins); 354 } 355 } 356 //When toggling between Aero and Classic theme the size of window changes 357 //No predefined WM_SIZE event type for this, so using -1 as parameters 358 HandleViewSizeEvent(GetHWND(), -1, -1, -1); 359 break; 360 case WM_SIZE: 361 switch (wParam) { 362 case SIZE_RESTORED: 363 if (m_state != Normal) { 364 HandleSizeEvent(com_sun_glass_events_WindowEvent_RESTORE, NULL); 365 m_state = Normal; 366 } else { 367 HandleSizeEvent(com_sun_glass_events_WindowEvent_RESIZE, NULL); 368 } 369 break; 370 case SIZE_MINIMIZED: 371 HandleSizeEvent(com_sun_glass_events_WindowEvent_MINIMIZE, NULL); 372 m_state = Minimized; 373 break; 374 case SIZE_MAXIMIZED: 375 HandleSizeEvent(com_sun_glass_events_WindowEvent_MAXIMIZE, NULL); 376 m_state = Maximized; 377 break; 378 } 379 HandleViewSizeEvent(GetHWND(), msg, wParam, lParam); 380 break; 381 // case WM_MOVING: 382 // HandleMoveEvent((RECT *)lParam); 383 // break; 384 case WM_MOVE: 385 HandleMoveEvent(NULL); 386 break; 387 case WM_WINDOWPOSCHANGED: 388 HandleWindowPosChangedEvent(); 389 break; 390 case WM_DPICHANGED: 391 HandleDPIEvent(wParam, lParam); 392 return 0; 393 case WM_CLOSE: 394 HandleCloseEvent(); 395 return 0; 396 case WM_DESTROY: 397 HandleDestroyEvent(); 398 return 0; 399 case WM_ACTIVATE: 400 { 401 // The fActive shouldn't be WA_INACTIVE && the window shouldn't be minimized: 402 const bool isFocusGained = LOWORD(wParam) != WA_INACTIVE && HIWORD(wParam) == 0; 403 404 if (IsInFullScreenMode()) { 405 HWND hWndInsertAfter = isFocusGained ? HWND_TOPMOST : HWND_BOTTOM; 406 ::SetWindowPos(GetHWND(), hWndInsertAfter, 0, 0, 0, 0, 407 SWP_ASYNCWINDOWPOS | SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOOWNERZORDER | SWP_NOSIZE); 408 } 409 if (!GetDelegateWindow()) { 410 HandleActivateEvent(isFocusGained ? 411 com_sun_glass_events_WindowEvent_FOCUS_GAINED : 412 com_sun_glass_events_WindowEvent_FOCUS_LOST); 413 } 414 } 415 // Let the DefWindowProc() set the focus to this window 416 break; 417 case WM_MOUSEACTIVATE: 418 if (!IsEnabled()) { 419 HandleFocusDisabledEvent(); 420 // Do not activate, and discard the event 421 return MA_NOACTIVATEANDEAT; 422 } 423 if (!IsFocusable()) { 424 // Do not activate, but pass the mouse event 425 return MA_NOACTIVATE; 426 } 427 break; 428 case WM_SETFOCUS: 429 if (!GetDelegateWindow()) { 430 SetFocused(true); 431 if (IsChild()) { 432 // Synthesize the event 433 HandleActivateEvent(m_focusEvent ? m_focusEvent : com_sun_glass_events_WindowEvent_FOCUS_GAINED); 434 m_focusEvent = 0; 435 } 436 } 437 break; 438 case WM_KILLFOCUS: 439 if (!GetDelegateWindow()) { 440 SetFocused(false); 441 if (IsChild()) { 442 // Synthesize the event 443 HandleActivateEvent(com_sun_glass_events_WindowEvent_FOCUS_LOST); 444 } 445 } 446 break; 447 case WM_GETMINMAXINFO: 448 if (m_minSize.x >= 0 || m_minSize.y >= 0 || 449 m_maxSize.x >= 0 || m_maxSize.y >= 0) 450 { 451 MINMAXINFO *info = (MINMAXINFO *)lParam; 452 if (m_minSize.x >= 0) { 453 info->ptMinTrackSize.x = m_minSize.x; 454 } 455 if (m_minSize.y >= 0) { 456 info->ptMinTrackSize.y = m_minSize.y; 457 } 458 if (m_maxSize.x >= 0) { 459 info->ptMaxTrackSize.x = m_maxSize.x; 460 } 461 if (m_maxSize.y >= 0) { 462 info->ptMaxTrackSize.y = m_maxSize.y; 463 } 464 return 0; 465 } 466 break; 467 case WM_COMMAND: 468 if (HandleCommand(LOWORD(wParam))) { 469 return 0; 470 } 471 break; 472 case WM_INPUTLANGCHANGE: 473 HandleViewInputLangChange(GetHWND(), msg, wParam, lParam); 474 return 0; 475 case WM_NCCALCSIZE: 476 // Workaround for RT-13998. It has some side effects and thus commented out 477 // if ((BOOL)wParam && !IsDecorated()) { 478 // NCCALCSIZE_PARAMS *p = (NCCALCSIZE_PARAMS *)lParam; 479 // p->rgrc[0].right++; 480 // p->rgrc[0].bottom++; 481 // return WVR_VALIDRECTS; 482 // } 483 break; 484 case WM_PAINT: 485 HandleViewPaintEvent(GetHWND(), msg, wParam, lParam); 486 break; 487 case WM_CONTEXTMENU: 488 HandleViewMenuEvent(GetHWND(), msg, wParam, lParam); 489 break; 490 case WM_LBUTTONDOWN: 491 case WM_RBUTTONDOWN: 492 case WM_MBUTTONDOWN: 493 CheckUngrab(); // check if other owned windows hierarchy holds the grab 494 if (IsChild() && !IsFocused() && IsFocusable()) { 495 RequestFocus(com_sun_glass_events_WindowEvent_FOCUS_GAINED); 496 } 497 // ... and fall through for other mouse events 498 case WM_LBUTTONUP: 499 case WM_LBUTTONDBLCLK: 500 case WM_RBUTTONUP: 501 case WM_RBUTTONDBLCLK: 502 case WM_MBUTTONUP: 503 case WM_MBUTTONDBLCLK: 504 case WM_MOUSEWHEEL: 505 case WM_MOUSEHWHEEL: 506 case WM_MOUSELEAVE: 507 case WM_MOUSEMOVE: 508 if (IsEnabled()) { 509 if (msg == WM_MOUSELEAVE && GetDelegateWindow()) { 510 // Skip generating MouseEvent.EXIT when entering FullScreen 511 return 0; 512 } 513 BOOL handled = HandleViewMouseEvent(GetHWND(), msg, wParam, lParam); 514 if (handled && msg == WM_RBUTTONUP) { 515 // By default, DefWindowProc() sends WM_CONTEXTMENU from WM_LBUTTONUP 516 // Since DefWindowProc() is not called, call the mouse menu handler directly 517 HandleViewMenuEvent(GetHWND(), WM_CONTEXTMENU, (WPARAM) GetHWND(), ::GetMessagePos ()); 518 //::DefWindowProc(GetHWND(), msg, wParam, lParam); 519 } 520 if (handled) { 521 // Do not call the DefWindowProc() for mouse events that were handled 522 return 0; 523 } 524 } else { 525 HandleFocusDisabledEvent(); 526 return 0; 527 } 528 break; 529 case WM_CAPTURECHANGED: 530 ViewContainer::NotifyCaptureChanged(GetHWND(), (HWND)lParam); 531 break; 532 case WM_SYSKEYDOWN: 533 case WM_SYSKEYUP: 534 case WM_KEYDOWN: 535 case WM_KEYUP: 536 if (!IsEnabled()) { 537 return 0; 538 } 539 HandleViewKeyEvent(GetHWND(), msg, wParam, lParam); 540 // Always pass the message down to the DefWindowProc() to handle 541 // system keys (Alt+F4, etc.) with only excpetion for F10 and ALT: 542 if (!GetMenu()) { 543 if (wParam == VK_MENU || (wParam == VK_F10 && !GetModifiers())) { 544 // Disable activation of the window's system menu 545 return 0; 546 } 547 } 548 break; 549 case WM_DEADCHAR: 550 if (IsEnabled()) HandleViewDeadKeyEvent(GetHWND(), msg, wParam, lParam); 551 break; 552 case WM_CHAR: 553 case WM_IME_CHAR: 554 if (IsEnabled()) { 555 HandleViewTypedEvent(GetHWND(), msg, wParam, lParam); 556 return 0; 557 } 558 break; 559 case WM_IME_COMPOSITION: 560 case WM_IME_ENDCOMPOSITION: 561 case WM_IME_NOTIFY: 562 case WM_IME_STARTCOMPOSITION: 563 if (IsEnabled() && 564 HandleViewInputMethodEvent(GetHWND(), msg, wParam, lParam)) { 565 return 0; 566 } 567 break; 568 case WM_NCLBUTTONDOWN: 569 case WM_NCMBUTTONDOWN: 570 case WM_NCRBUTTONDOWN: 571 case WM_NCXBUTTONDOWN: 572 UngrabFocus(); // ungrab itself 573 CheckUngrab(); // check if other owned windows hierarchy holds the grab 574 // Pass the event to DefWindowProc() 575 break; 576 case WM_TOUCH: 577 if (IsEnabled()) { 578 HandleViewTouchEvent(GetHWND(), msg, wParam, lParam); 579 return 0; 580 } 581 break; 582 case WM_TIMER: 583 HandleViewTimerEvent(GetHWND(), wParam); 584 return 0; 585 case WM_GETOBJECT: { 586 LRESULT lr = HandleViewGetAccessible(GetHWND(), wParam, lParam); 587 if (lr) return lr; 588 break; 589 } 590 } 591 592 return ::DefWindowProc(GetHWND(), msg, wParam, lParam); 593 } 594 595 void GlassWindow::HandleCloseEvent() 596 { 597 JNIEnv* env = GetEnv(); 598 599 env->CallVoidMethod(m_grefThis, midNotifyClose); 600 CheckAndClearException(env); 601 } 602 603 void GlassWindow::HandleDestroyEvent() 604 { 605 JNIEnv* env = GetEnv(); 606 607 env->CallVoidMethod(m_grefThis, javaIDs.Window.notifyDestroy); 608 CheckAndClearException(env); 609 } 610 611 // if pRect == NULL => get position/size by GetWindowRect 612 void GlassWindow::HandleMoveEvent(RECT *pRect) 613 { 614 JNIEnv* env = GetEnv(); 615 616 RECT r; 617 if (pRect == NULL) { 618 ::GetWindowRect(GetHWND(), &r); 619 pRect = &r; 620 } 621 622 env->CallVoidMethod(m_grefThis, midNotifyMove, pRect->left, pRect->top); 623 CheckAndClearException(env); 624 } 625 626 // if pRect == NULL => get position/size by GetWindowRect 627 void GlassWindow::HandleSizeEvent(int type, RECT *pRect) 628 { 629 JNIEnv* env = GetEnv(); 630 631 RECT r; 632 if (pRect == NULL) { 633 ::GetWindowRect(GetHWND(), &r); 634 pRect = &r; 635 } 636 637 env->CallVoidMethod(m_grefThis, midNotifyResize, 638 type, pRect->right-pRect->left, pRect->bottom-pRect->top); 639 CheckAndClearException(env); 640 } 641 642 void GlassWindow::HandleDPIEvent(WPARAM wParam, LPARAM lParam) { 643 UINT xDPI = LOWORD(wParam); 644 UINT yDPI = HIWORD(wParam); 645 646 // fprintf(stderr, "DPI Changed (=> %d, %d)!\n", yDPI, xDPI); 647 JNIEnv* env = GetEnv(); 648 jfloat newUIScale = GlassApplication::GetUIScale(xDPI); 649 jfloat newRenderScale = GlassApplication::getRenderScale(newUIScale); 650 env->CallVoidMethod(m_grefThis, midNotifyScaleChanged, newUIScale, newRenderScale); 651 CheckAndClearException(env); 652 653 LPRECT lprcNewScale = (LPRECT) lParam; 654 #if 0 655 RECT oldBounds, oldClient; 656 ::GetWindowRect(GetHWND(), &oldBounds); 657 ::GetClientRect(GetHWND(), &oldClient); 658 POINT cursor; 659 ::GetCursorPos(&cursor); 660 fprintf(stderr, " @ %d, %d\n", cursor.x, cursor.y); 661 fprintf(stderr, " (%d, %d, %d, %d) [%d x %d] in (%d, %d, %d, %d) [%d x %d] => (%d, %d, %d, %d) [%d x %d]\n", 662 oldClient.left, oldClient.top, oldClient.right, oldClient.bottom, 663 oldClient.right - oldClient.left, oldClient.bottom - oldClient.top, 664 oldBounds.left, oldBounds.top, oldBounds.right, oldBounds.bottom, 665 oldBounds.right - oldBounds.left, oldBounds.bottom - oldBounds.top, 666 lprcNewScale->left, lprcNewScale->top, lprcNewScale->right, lprcNewScale->bottom, 667 lprcNewScale->right - lprcNewScale->left, lprcNewScale->bottom - lprcNewScale->top); 668 #endif 669 ::SetWindowPos(GetHWND(), HWND_TOP, 670 lprcNewScale->left, 671 lprcNewScale->top, 672 lprcNewScale->right - lprcNewScale->left, 673 lprcNewScale->bottom - lprcNewScale->top, 674 SWP_NOZORDER | SWP_NOACTIVATE); 675 } 676 677 void GlassWindow::HandleWindowPosChangedEvent() 678 { 679 JNIEnv* env = GetEnv(); 680 681 HMONITOR toMonitor = ::MonitorFromWindow(GetHWND(), MONITOR_DEFAULTTOPRIMARY); 682 HMONITOR fromMonitor = GetMonitor(); 683 if (toMonitor != fromMonitor) { 684 // fprintf(stderr, "Monitor changed!\n"); 685 env->CallVoidMethod(m_grefThis, midNotifyMoveToAnotherScreen, 686 GlassScreen::GetJavaMonitor(env, toMonitor)); 687 CheckAndClearException(env); 688 SetMonitor(toMonitor); 689 } 690 } 691 692 void GlassWindow::HandleActivateEvent(jint event) 693 { 694 const bool active = event != com_sun_glass_events_WindowEvent_FOCUS_LOST; 695 696 if (!active) { 697 UngrabFocus(); 698 } 699 700 JNIEnv* env = GetEnv(); 701 env->CallVoidMethod(m_grefThis, javaIDs.Window.notifyFocus, event); 702 CheckAndClearException(env); 703 } 704 705 void GlassWindow::HandleFocusDisabledEvent() 706 { 707 JNIEnv* env = GetEnv(); 708 709 env->CallVoidMethod(m_grefThis, javaIDs.Window.notifyFocusDisabled); 710 CheckAndClearException(env); 711 } 712 713 bool GlassWindow::HandleCommand(WORD cmdID) { 714 return HandleMenuCommand(GetHWND(), cmdID); 715 } 716 717 HMONITOR GlassWindow::GetMonitor() 718 { 719 return m_hMonitor; 720 } 721 722 void GlassWindow::SetMonitor(HMONITOR hMonitor) 723 { 724 m_hMonitor = hMonitor; 725 } 726 727 void GlassWindow::SetAlpha(BYTE alpha) 728 { 729 m_alpha = alpha; 730 731 if (m_isTransparent) { 732 // If the window is transparent, the opacity is handled in 733 // uploadPixels() below (see BLENDFUNCTION structure 734 // and its SourceConstantAlpha member) 735 return; 736 } 737 738 // The window is opaque. We make it layered temporarily only when 739 // its alpha is less than 0xFF. 740 LONG exStyle = ::GetWindowLong(GetHWND(), GWL_EXSTYLE); 741 742 if (alpha == 0xFF) { 743 if (exStyle & WS_EX_LAYERED) { 744 ::SetWindowLong(GetHWND(), GWL_EXSTYLE, exStyle & ~WS_EX_LAYERED); 745 } 746 } else { 747 if (!(exStyle & WS_EX_LAYERED)) { 748 ::SetWindowLong(GetHWND(), GWL_EXSTYLE, exStyle | WS_EX_LAYERED); 749 } 750 ::SetLayeredWindowAttributes(GetHWND(), RGB(0, 0, 0), alpha, LWA_ALPHA); 751 } 752 } 753 754 void GlassWindow::UpdateInsets() 755 { 756 if (::IsIconic(GetHWND())) { 757 return; 758 } 759 760 RECT outer, inner; 761 762 ::GetWindowRect(GetHWND(), &outer); 763 ::GetClientRect(GetHWND(), &inner); 764 765 ::MapWindowPoints(GetHWND(), (HWND)NULL, (LPPOINT)&inner, (sizeof(RECT)/sizeof(POINT))); 766 767 m_insets.top = inner.top - outer.top; 768 m_insets.left = inner.left - outer.left; 769 m_insets.bottom = outer.bottom - inner.bottom; 770 m_insets.right = outer.right - inner.right; 771 772 if (m_insets.top < 0 || m_insets.left < 0 || 773 m_insets.bottom < 0 || m_insets.right < 0) 774 { 775 if (!IsDecorated()) { 776 ::ZeroMemory(&m_insets, sizeof(m_insets)); 777 } else { 778 if (GetStyle() & WS_THICKFRAME) { 779 m_insets.left = m_insets.right = 780 ::GetSystemMetrics(SM_CXSIZEFRAME); 781 m_insets.top = m_insets.bottom = 782 ::GetSystemMetrics(SM_CYSIZEFRAME); 783 } else { 784 m_insets.left = m_insets.right = 785 ::GetSystemMetrics(SM_CXDLGFRAME); 786 m_insets.top = m_insets.bottom = 787 ::GetSystemMetrics(SM_CYDLGFRAME); 788 } 789 790 m_insets.top += ::GetSystemMetrics(SM_CYCAPTION); 791 } 792 if (GetMenu()) { 793 //Well, if menu wraps on multiple lines... sorry about that. 794 m_insets.top += ::GetSystemMetrics(SM_CYMENU); 795 } 796 } 797 } 798 799 bool GlassWindow::SetResizable(bool resizable) 800 { 801 LONG style = GetStyle(); 802 803 if (style & WS_CHILD) { 804 return false; 805 } 806 807 LONG resizableStyle = WS_MAXIMIZEBOX; 808 if (IsDecorated()) { 809 resizableStyle |= WS_THICKFRAME; 810 } 811 812 if (resizable) { 813 style |= resizableStyle; 814 } else { 815 style &= ~resizableStyle; 816 } 817 818 SetStyle(style); 819 m_isResizable = resizable; 820 821 return true; 822 } 823 824 /* static */ void GlassWindow::ResetGrab() 825 { 826 if (sm_grabWindow) { 827 GlassWindow *pWindow = GlassWindow::FromHandle(sm_grabWindow); 828 if (pWindow) { 829 pWindow->UngrabFocus(); 830 } 831 sm_grabWindow = NULL; 832 } 833 } 834 835 bool GlassWindow::GrabFocus() 836 { 837 HWND hwnd = GetCurrentHWND(); 838 839 if (sm_grabWindow == hwnd) { 840 // Already grabbed 841 return true; 842 } 843 844 GlassWindow::ResetGrab(); 845 846 sm_grabWindow = hwnd; 847 848 return true; 849 } 850 851 void GlassWindow::UngrabFocus() 852 { 853 HWND hwnd = GetCurrentHWND(); 854 855 if (hwnd != sm_grabWindow) { 856 return; 857 } 858 859 JNIEnv* env = GetEnv(); 860 env->CallVoidMethod(m_grefThis, javaIDs.Window.notifyFocusUngrab); 861 CheckAndClearException(env); 862 863 sm_grabWindow = NULL; 864 } 865 866 void GlassWindow::CheckUngrab() 867 { 868 if (!sm_grabWindow) { 869 return; 870 } 871 872 // If this window doesn't belong to an owned windows hierarchy that 873 // holds the grab currently, then the grab should be released. 874 // Fix RT-16490: use GetAncestor() instead of ::GetParent() to support embedded windows 875 for (BaseWnd * window = this; window != NULL; window = BaseWnd::FromHandle(window->GetAncestor())) { 876 if (window->GetHWND() == sm_grabWindow) { 877 return; 878 } 879 } 880 881 GlassWindow::ResetGrab(); 882 } 883 884 bool GlassWindow::RequestFocus(jint event) 885 { 886 if (!IsChild()) { 887 ASSERT(event == com_sun_glass_events_WindowEvent_FOCUS_GAINED); 888 // The event will be delivered as a part of WM_ACTIVATE message handling 889 return ::SetForegroundWindow(GetHWND()) != FALSE; 890 } 891 892 if (event == com_sun_glass_events_WindowEvent_FOCUS_LOST) { 893 if (IsFocused()) { 894 ::SetFocus(NULL); 895 } 896 897 return true; 898 } 899 900 // First try to activate the toplevel window 901 HWND toplevel = ::GetAncestor(GetHWND(), GA_ROOT); 902 if (::GetForegroundWindow() != toplevel && !::SetForegroundWindow(toplevel)) { 903 // We're unable to bring our top-level window to foreground. 904 // But since it anyway becomes active, we (or the plugin) won't receive 905 // any subsequent notifications. So let's pretend we got the focus - 906 //IGNORE: return false; 907 //We'll anyway get a reasonable response from the ::SetFocus() later 908 } 909 910 m_focusEvent = event; // reset upon WM_SETFOCUS 911 912 // If we request focus from 'nowhere', the SetFocus may still return NULL I guess 913 return ::SetFocus(GetHWND()) != NULL || ::GetLastError() == 0; 914 } 915 916 static BOOL CALLBACK EnumChildWndProc(HWND hwnd, LPARAM lParam) 917 { 918 HWND * hwnds = (HWND*)lParam; 919 920 ::SetParent(hwnd, hwnds[1]); 921 922 BaseWnd * window = BaseWnd::FromHandle(hwnd); 923 if (window) { 924 window->SetAncestor(hwnds[1]); 925 } 926 927 return TRUE; 928 } 929 930 static BOOL CALLBACK EnumOwnedWndProc(HWND hwnd, LPARAM lParam) 931 { 932 HWND * hwnds = (HWND*)lParam; 933 934 GlassWindow * window = NULL; 935 if ((HWND)::GetWindowLongPtr(hwnd, GWLP_HWNDPARENT) == hwnds[0] && (window = GlassWindow::FromHandle(hwnd)) != NULL) { 936 ::SetWindowLongPtr(hwnd, GWLP_HWNDPARENT, (LONG_PTR)hwnds[1]); 937 window->SetAncestor(hwnds[1]); 938 ::SetWindowPos(hwnd, hwnds[1], 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_FRAMECHANGED | SWP_NOACTIVATE); 939 } 940 941 return TRUE; 942 } 943 944 void GlassWindow::SetDelegateWindow(HWND hWnd) 945 { 946 if (m_delegateWindow == hWnd) { 947 return; 948 } 949 950 // Make sure any popups are hidden 951 UngrabFocus(); 952 953 HWND hwnds[2]; // [0] = from; [1] = to; 954 955 hwnds[0] = m_delegateWindow ? m_delegateWindow : GetHWND(); 956 hwnds[1] = hWnd ? hWnd : GetHWND(); 957 958 STRACE(_T("SetDelegateWindow: from %p to %p"), hwnds[0], hwnds[1]); 959 960 // Reparent child, and then owned windows 961 ::EnumChildWindows(hwnds[0], &EnumChildWndProc, (LPARAM)&hwnds); 962 ::EnumThreadWindows(GlassApplication::GetMainThreadId(), &EnumOwnedWndProc, (LPARAM)&hwnds); 963 964 m_delegateWindow = hWnd; 965 966 GetEnv()->CallVoidMethod(m_grefThis, 967 javaIDs.Window.notifyDelegatePtr, (jlong)hWnd); 968 CheckAndClearException(GetEnv()); 969 } 970 971 BOOL GlassWindow::EnterFullScreenMode(GlassView * view, BOOL animate, BOOL keepRatio) 972 { 973 if (IsChild()) { 974 return FALSE; 975 } 976 if (IsInFullScreenMode()) { 977 return TRUE; 978 } 979 if (view != GetGlassView()) { 980 STRACE(_T("EnterFullScreenMode(view = %p) while the real view for this window is: %p"), view, GetGlassView()); 981 return FALSE; 982 } 983 984 static const LONG FS_STYLE_MASK = WS_CAPTION | WS_MINIMIZEBOX | WS_MAXIMIZEBOX | WS_BORDER | WS_THICKFRAME; 985 static const LONG FS_EXSTYLE_MASK = WS_EX_WINDOWEDGE; 986 987 LONG style = ::GetWindowLong(GetHWND(), GWL_STYLE); 988 LONG exStyle = ::GetWindowLong(GetHWND(), GWL_EXSTYLE); 989 990 ::GetWindowRect(GetHWND(), &m_beforeFullScreenRect); 991 m_beforeFullScreenStyle = style & FS_STYLE_MASK; 992 m_beforeFullScreenExStyle = exStyle & FS_EXSTYLE_MASK; 993 m_beforeFullScreenMenu = ::GetMenu(GetHWND()); 994 995 RECT viewRect, screenRect, contentRect; 996 997 FullScreenWindow::ClientRectInScreen(GetHWND(), &viewRect); 998 FullScreenWindow::CalculateBounds(GetHWND(), &screenRect, 999 &contentRect, keepRatio, viewRect); 1000 1001 //XXX: if (keepRatio) initBlackBackground(screenRect); 1002 1003 ::SetWindowLong(GetHWND(), GWL_STYLE, style & ~FS_STYLE_MASK); 1004 ::SetWindowLong(GetHWND(), GWL_EXSTYLE, exStyle & ~FS_EXSTYLE_MASK); 1005 1006 ::SetMenu(GetHWND(), NULL); 1007 1008 ::SetWindowPos(GetHWND(), HWND_TOPMOST, 1009 contentRect.left, contentRect.top, 1010 contentRect.right - contentRect.left, contentRect.bottom - contentRect.top, 1011 SWP_FRAMECHANGED | SWP_NOCOPYBITS); 1012 1013 m_isInFullScreen = true; 1014 1015 return TRUE; 1016 } 1017 1018 void GlassWindow::ExitFullScreenMode(BOOL animate) 1019 { 1020 if (IsChild() || !IsInFullScreenMode()) { 1021 return; 1022 } 1023 1024 LONG style = ::GetWindowLong(GetHWND(), GWL_STYLE); 1025 LONG exStyle = ::GetWindowLong(GetHWND(), GWL_EXSTYLE); 1026 1027 ::SetWindowLong(GetHWND(), GWL_STYLE, style | m_beforeFullScreenStyle); 1028 ::SetWindowLong(GetHWND(), GWL_EXSTYLE, exStyle | m_beforeFullScreenExStyle); 1029 1030 ::SetMenu(GetHWND(), m_beforeFullScreenMenu); 1031 1032 LONG swpFlags = SWP_FRAMECHANGED | SWP_NOCOPYBITS; 1033 if (!IsFocused()) { 1034 swpFlags |= SWP_NOACTIVATE; 1035 } 1036 ::SetWindowPos(GetHWND(), HWND_NOTOPMOST, 1037 m_beforeFullScreenRect.left, m_beforeFullScreenRect.top, 1038 m_beforeFullScreenRect.right - m_beforeFullScreenRect.left, 1039 m_beforeFullScreenRect.bottom - m_beforeFullScreenRect.top, 1040 swpFlags); 1041 1042 m_isInFullScreen = false; 1043 } 1044 1045 void GlassWindow::SetEnabled(bool enabled) 1046 { 1047 if (!enabled) { 1048 ResetMouseTracking(GetHWND()); 1049 } 1050 1051 m_isEnabled = enabled; 1052 } 1053 1054 void GlassWindow::SetIcon(HICON hIcon) 1055 { 1056 ::SendMessage(GetHWND(), WM_SETICON, ICON_SMALL, (LPARAM)hIcon); 1057 ::SendMessage(GetHWND(), WM_SETICON, ICON_BIG, (LPARAM)hIcon); 1058 1059 if (m_hIcon) { 1060 ::DestroyIcon(m_hIcon); 1061 } 1062 m_hIcon = hIcon; 1063 } 1064 1065 /* 1066 * JNI methods section 1067 * 1068 */ 1069 1070 extern "C" { 1071 1072 /* 1073 * Class: com_sun_glass_ui_win_WinWindow 1074 * Method: _initIDs 1075 * Signature: ()V 1076 */ 1077 JNIEXPORT void JNICALL Java_com_sun_glass_ui_win_WinWindow__1initIDs 1078 (JNIEnv *env, jclass cls) 1079 { 1080 midNotifyClose = env->GetMethodID(cls, "notifyClose", "()V"); 1081 ASSERT(midNotifyClose); 1082 if (env->ExceptionCheck()) return; 1083 1084 midNotifyMove = env->GetMethodID(cls, "notifyMove", "(II)V"); 1085 ASSERT(midNotifyMove); 1086 if (env->ExceptionCheck()) return; 1087 1088 midNotifyResize = env->GetMethodID(cls, "notifyResize", "(III)V"); 1089 ASSERT(midNotifyResize); 1090 if (env->ExceptionCheck()) return; 1091 1092 midNotifyScaleChanged = env->GetMethodID(cls, "notifyScaleChanged", "(FF)V"); 1093 ASSERT(midNotifyScaleChanged); 1094 if (env->ExceptionCheck()) return; 1095 1096 javaIDs.Window.notifyFocus = env->GetMethodID(cls, "notifyFocus", "(I)V"); 1097 ASSERT(javaIDs.Window.notifyFocus); 1098 if (env->ExceptionCheck()) return; 1099 1100 javaIDs.Window.notifyFocusDisabled = env->GetMethodID(cls, "notifyFocusDisabled", "()V"); 1101 ASSERT(javaIDs.Window.notifyFocusDisabled); 1102 if (env->ExceptionCheck()) return; 1103 1104 javaIDs.Window.notifyFocusUngrab = env->GetMethodID(cls, "notifyFocusUngrab", "()V"); 1105 ASSERT(javaIDs.Window.notifyFocusUngrab); 1106 if (env->ExceptionCheck()) return; 1107 1108 midNotifyMoveToAnotherScreen = env->GetMethodID(cls, "notifyMoveToAnotherScreen", "(Lcom/sun/glass/ui/Screen;)V"); 1109 ASSERT(midNotifyMoveToAnotherScreen); 1110 if (env->ExceptionCheck()) return; 1111 1112 javaIDs.Window.notifyDestroy = env->GetMethodID(cls, "notifyDestroy", "()V"); 1113 ASSERT(javaIDs.Window.notifyDestroy); 1114 if (env->ExceptionCheck()) return; 1115 1116 javaIDs.Window.notifyDelegatePtr = env->GetMethodID(cls, "notifyDelegatePtr", "(J)V"); 1117 ASSERT(javaIDs.Window.notifyDelegatePtr); 1118 if (env->ExceptionCheck()) return; 1119 } 1120 1121 /* 1122 * Class: com_sun_glass_ui_win_WinWindow 1123 * Method: _createWindow 1124 * Signature: (JJZI)J 1125 */ 1126 JNIEXPORT jlong JNICALL Java_com_sun_glass_ui_win_WinWindow__1createWindow 1127 (JNIEnv *env, jobject jThis, jlong ownerPtr, jlong screenPtr, jint mask) 1128 { 1129 ENTER_MAIN_THREAD_AND_RETURN(jlong) 1130 { 1131 DWORD dwStyle; 1132 DWORD dwExStyle; 1133 bool closeable; 1134 1135 dwStyle = WS_CLIPCHILDREN | WS_SYSMENU; 1136 closeable = (mask & com_sun_glass_ui_Window_CLOSABLE) != 0; 1137 1138 if (mask & com_sun_glass_ui_Window_TITLED) { 1139 dwExStyle = WS_EX_WINDOWEDGE; 1140 dwStyle |= WS_CAPTION; 1141 1142 if (mask & com_sun_glass_ui_Window_MINIMIZABLE) { 1143 dwStyle |= WS_MINIMIZEBOX; 1144 } 1145 if (mask & com_sun_glass_ui_Window_MAXIMIZABLE) { 1146 dwStyle |= WS_MAXIMIZEBOX; 1147 } 1148 } else { 1149 dwExStyle = 0; 1150 dwStyle |= WS_POPUP; 1151 } 1152 1153 if (mask & com_sun_glass_ui_Window_TRANSPARENT) { 1154 dwExStyle |= WS_EX_LAYERED; 1155 } 1156 1157 if (mask & com_sun_glass_ui_Window_POPUP) { 1158 dwStyle |= WS_POPUP; 1159 // Popups should not appear in the taskbar, so WS_EX_TOOLWINDOW 1160 dwExStyle |= WS_EX_TOOLWINDOW; 1161 } 1162 1163 if (mask & com_sun_glass_ui_Window_UTILITY) { 1164 dwExStyle |= WS_EX_TOOLWINDOW; 1165 } 1166 1167 if (mask & com_sun_glass_ui_Window_RIGHT_TO_LEFT) { 1168 dwExStyle |= WS_EX_NOINHERITLAYOUT | WS_EX_LAYOUTRTL; 1169 } 1170 1171 GlassWindow *pWindow = 1172 new GlassWindow(jThis, 1173 (mask & com_sun_glass_ui_Window_TRANSPARENT) != 0, 1174 (mask & com_sun_glass_ui_Window_TITLED) != 0, 1175 (mask & com_sun_glass_ui_Window_UNIFIED) != 0, 1176 false, 1177 owner); 1178 1179 HWND hWnd = pWindow->Create(dwStyle, dwExStyle, hMonitor, owner); 1180 1181 if (!hWnd) { 1182 delete pWindow; 1183 } else { 1184 if (!closeable) { 1185 HMENU hSysMenu = ::GetSystemMenu(hWnd, FALSE); 1186 if (hSysMenu != NULL) { 1187 ::EnableMenuItem(hSysMenu, SC_CLOSE, 1188 MF_BYCOMMAND | MF_DISABLED | MF_GRAYED); 1189 } 1190 } 1191 } 1192 1193 return (jlong)hWnd; 1194 } 1195 DECL_jobject(jThis); 1196 HWND owner; 1197 HMONITOR hMonitor; 1198 jint mask; 1199 LEAVE_MAIN_THREAD; 1200 1201 ARG(jThis) = jThis; 1202 ARG(owner) = (HWND)ownerPtr; 1203 ARG(hMonitor) = (HMONITOR)screenPtr; 1204 ARG(mask) = mask; 1205 1206 return PERFORM_AND_RETURN(); 1207 } 1208 1209 /* 1210 * Class: com_sun_glass_ui_win_WinWindow 1211 * Method: _createChildWindow 1212 * Signature: (J)J 1213 */ 1214 JNIEXPORT jlong JNICALL Java_com_sun_glass_ui_win_WinWindow__1createChildWindow 1215 (JNIEnv *env, jobject jThis, jlong parentPtr) 1216 { 1217 ENTER_MAIN_THREAD_AND_RETURN(jlong) 1218 { 1219 // Check that the 'parent' isn't a garbage value 1220 if (!::IsWindow((HWND)parent)) { 1221 return (jlong)0; 1222 } 1223 1224 DWORD dwStyle; 1225 DWORD dwExStyle; 1226 1227 dwStyle = WS_CLIPCHILDREN | WS_CLIPSIBLINGS | WS_CHILD; 1228 dwExStyle = WS_EX_NOINHERITLAYOUT; 1229 1230 GlassWindow *pWindow = 1231 new GlassWindow(jThis, false, false, false, true, parent); 1232 1233 HWND hWnd = pWindow->Create(dwStyle, dwExStyle, NULL, parent); 1234 1235 if (!hWnd) { 1236 delete pWindow; 1237 } 1238 pWindow->HandleWindowPosChangedEvent(); 1239 1240 return (jlong)hWnd; 1241 } 1242 DECL_jobject(jThis); 1243 HWND parent; 1244 LEAVE_MAIN_THREAD; 1245 1246 ARG(jThis) = jThis; 1247 ARG(parent) = (HWND)parentPtr; 1248 1249 return PERFORM_AND_RETURN(); 1250 } 1251 /* 1252 * Class: com_sun_glass_ui_win_WinWindow 1253 * Method: _close 1254 * Signature: (J)Z 1255 */ 1256 JNIEXPORT jboolean JNICALL Java_com_sun_glass_ui_win_WinWindow__1close 1257 (JNIEnv *env, jobject jThis, jlong ptr) 1258 { 1259 ENTER_MAIN_THREAD_AND_RETURN(jboolean) 1260 { 1261 GlassWindow *pWindow = GlassWindow::FromHandle(hWnd); 1262 pWindow->Close(); 1263 return bool_to_jbool(::DestroyWindow(hWnd)); 1264 } 1265 LEAVE_MAIN_THREAD_WITH_hWnd; 1266 1267 return PERFORM_AND_RETURN(); 1268 } 1269 1270 /* 1271 * Class: com_sun_glass_ui_win_WinWindow 1272 * Method: _setView 1273 * Signature: (JJ)Z 1274 */ 1275 JNIEXPORT jboolean JNICALL Java_com_sun_glass_ui_win_WinWindow__1setView 1276 (JNIEnv * env, jobject jThis, jlong ptr, jobject view) 1277 { 1278 ENTER_MAIN_THREAD() 1279 { 1280 GlassWindow *pWindow = GlassWindow::FromHandle(hWnd); 1281 pWindow->ResetMouseTracking(hWnd); 1282 pWindow->SetGlassView(view); 1283 // The condition below may be restricted to WS_POPUP windows 1284 if (::IsWindowVisible(hWnd)) { 1285 pWindow->NotifyViewSize(hWnd); 1286 } 1287 } 1288 GlassView * view; 1289 LEAVE_MAIN_THREAD_WITH_hWnd; 1290 1291 ARG(view) = view == NULL ? NULL : (GlassView*)env->GetLongField(view, javaIDs.View.ptr); 1292 1293 PERFORM(); 1294 return JNI_TRUE; 1295 } 1296 1297 /* 1298 * Class: com_sun_glass_ui_win_WinWindow 1299 * Method: _setMenubar 1300 * Signature: (JJ)Z 1301 */ 1302 JNIEXPORT jboolean JNICALL Java_com_sun_glass_ui_win_WinWindow__1setMenubar 1303 (JNIEnv *env, jobject jThis, jlong ptr, jlong menuPtr) 1304 { 1305 ENTER_MAIN_THREAD_AND_RETURN(jboolean) 1306 { 1307 if (::SetMenu(hWnd, hMenu)) 1308 { 1309 GlassWindow *pWindow = GlassWindow::FromHandle(hWnd); 1310 if (pWindow) { 1311 pWindow->SetMenu(hMenu); 1312 } 1313 1314 return JNI_TRUE; 1315 } 1316 return JNI_FALSE; 1317 } 1318 HMENU hMenu; 1319 LEAVE_MAIN_THREAD_WITH_hWnd; 1320 1321 ARG(hMenu) = (HMENU)menuPtr; 1322 return PERFORM_AND_RETURN(); 1323 } 1324 1325 /* 1326 * Class: com_sun_glass_ui_win_WinWindow 1327 * Method: _setLevel 1328 * Signature: (JI)V 1329 */ 1330 JNIEXPORT void JNICALL Java_com_sun_glass_ui_win_WinWindow__1setLevel 1331 (JNIEnv *env, jobject jwindow, jlong ptr, jint jLevel) 1332 { 1333 ENTER_MAIN_THREAD() 1334 { 1335 ::SetWindowPos(hWnd, hWndInsertAfter, 0, 0, 0, 0, 1336 SWP_ASYNCWINDOWPOS | SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOOWNERZORDER | SWP_NOSIZE); 1337 } 1338 HWND hWndInsertAfter; 1339 LEAVE_MAIN_THREAD_WITH_hWnd; 1340 1341 ARG(hWndInsertAfter) = HWND_NOTOPMOST; 1342 switch (jLevel) { 1343 case com_sun_glass_ui_Window_Level_FLOATING: 1344 case com_sun_glass_ui_Window_Level_TOPMOST: 1345 ARG(hWndInsertAfter) = HWND_TOPMOST; 1346 break; 1347 } 1348 PERFORM(); 1349 } 1350 1351 /* 1352 * Class: com_sun_glass_ui_win_WinWindow 1353 * Method: _setFocusable 1354 * Signature: (JZ)V 1355 */ 1356 JNIEXPORT void JNICALL Java_com_sun_glass_ui_win_WinWindow__1setFocusable 1357 (JNIEnv *env, jobject jwindow, jlong ptr, jboolean isFocusable) 1358 { 1359 ENTER_MAIN_THREAD() 1360 { 1361 GlassWindow *pWindow = GlassWindow::FromHandle(hWnd); 1362 pWindow->SetFocusable(isFocusable); 1363 } 1364 bool isFocusable; 1365 LEAVE_MAIN_THREAD_WITH_hWnd; 1366 1367 ARG(isFocusable) = isFocusable == JNI_TRUE; 1368 PERFORM(); 1369 } 1370 1371 /* 1372 * Class: com_sun_glass_ui_win_WinWindow 1373 * Method: _setEnabled 1374 * Signature: (JZ)V 1375 */ 1376 JNIEXPORT void JNICALL Java_com_sun_glass_ui_win_WinWindow__1setEnabled 1377 (JNIEnv *env, jobject jwindow, jlong ptr, jboolean isEnabled) 1378 { 1379 ENTER_MAIN_THREAD() 1380 { 1381 GlassWindow *pWindow = GlassWindow::FromHandle(hWnd); 1382 pWindow->SetEnabled(isEnabled); 1383 ::EnableWindow(hWnd, isEnabled); 1384 } 1385 bool isEnabled; 1386 LEAVE_MAIN_THREAD_WITH_hWnd; 1387 1388 ARG(isEnabled) = isEnabled == JNI_TRUE; 1389 PERFORM(); 1390 } 1391 1392 // Converts a float [0..1] to a BYTE [0..255] 1393 #define F2B(value) BYTE(255.f * (value)) 1394 1395 /* 1396 * Class: com_sun_glass_ui_win_WinWindow 1397 * Method: _setAlpha 1398 * Signature: (JF)V 1399 */ 1400 JNIEXPORT void JNICALL Java_com_sun_glass_ui_win_WinWindow__1setAlpha 1401 (JNIEnv *env, jobject jThis, jlong ptr, jfloat alpha) 1402 { 1403 ENTER_MAIN_THREAD() 1404 { 1405 GlassWindow *pWindow = GlassWindow::FromHandle(hWnd); 1406 pWindow->SetAlpha(alpha); 1407 } 1408 BYTE alpha; 1409 LEAVE_MAIN_THREAD_WITH_hWnd; 1410 1411 ARG(alpha) = F2B(alpha); 1412 PERFORM(); 1413 } 1414 1415 /* 1416 * Class: com_sun_glass_ui_win_WinWindow 1417 * Method: _setBackground 1418 * Signature: (JFFF)Z 1419 */ 1420 JNIEXPORT jboolean JNICALL Java_com_sun_glass_ui_win_WinWindow__1setBackground 1421 (JNIEnv *env, jobject jThis, jlong ptr, jfloat r, jfloat g, jfloat b) 1422 { 1423 ENTER_MAIN_THREAD() 1424 { 1425 HBRUSH hbrBackground; 1426 1427 // That's a hack with 'negative' color 1428 if (r < 0) { 1429 hbrBackground = NULL; 1430 } else { 1431 hbrBackground = ::CreateSolidBrush(RGB(F2B(r), F2B(g), F2B(b))); 1432 } 1433 1434 HBRUSH oldBrush = (HBRUSH)::SetClassLongPtr(hWnd, GCLP_HBRBACKGROUND, (LONG_PTR)hbrBackground); 1435 1436 if (oldBrush) { 1437 ::DeleteObject(oldBrush); 1438 } 1439 } 1440 jfloat r, g, b; 1441 LEAVE_MAIN_THREAD_WITH_hWnd; 1442 1443 ARG(r) = r; 1444 ARG(g) = g; 1445 ARG(b) = b; 1446 PERFORM(); 1447 1448 return JNI_TRUE; 1449 } 1450 1451 /* 1452 * Class: com_sun_glass_ui_win_WinWindow 1453 * Method: _setBounds 1454 * Signature: (JIIZZIIIIFF)Z 1455 */ 1456 JNIEXPORT void JNICALL Java_com_sun_glass_ui_win_WinWindow__1setBounds 1457 (JNIEnv *env, jobject jThis, jlong ptr, 1458 jint x, jint y, jboolean xSet, jboolean ySet, 1459 jint w, jint h, jint cw, jint ch, 1460 jfloat xGravity, jfloat yGravity) 1461 { 1462 ENTER_MAIN_THREAD() 1463 { 1464 if (!::IsWindow(hWnd)) return; 1465 GlassWindow *pWindow = GlassWindow::FromHandle(hWnd); 1466 1467 pWindow->UpdateInsets(); 1468 RECT is = pWindow->GetInsets(); 1469 1470 RECT r; 1471 ::GetWindowRect(hWnd, &r); 1472 1473 int newX = jbool_to_bool(xSet) ? x : r.left; 1474 int newY = jbool_to_bool(ySet) ? y : r.top; 1475 int newW = w > 0 ? w : 1476 cw > 0 ? cw + is.right + is.left : r.right - r.left; 1477 int newH = h > 0 ? h : 1478 ch > 0 ? ch + is.bottom + is.top : r.bottom - r.top; 1479 1480 if (xSet || ySet) { 1481 ::SetWindowPos(hWnd, NULL, newX, newY, newW, newH, 1482 SWP_NOACTIVATE | SWP_NOZORDER); 1483 } else { 1484 ::SetWindowPos(hWnd, NULL, 0, 0, newW, newH, 1485 SWP_NOACTIVATE | SWP_NOZORDER | SWP_NOMOVE); 1486 } 1487 } 1488 jint x, y; 1489 jboolean xSet, ySet; 1490 jint w, h, cw, ch; 1491 LEAVE_MAIN_THREAD_WITH_hWnd; 1492 1493 ARG(x) = x; 1494 ARG(y) = y; 1495 ARG(xSet) = xSet; 1496 ARG(ySet) = ySet; 1497 ARG(w) = w; 1498 ARG(h) = h; 1499 ARG(cw) = cw; 1500 ARG(ch) = ch; 1501 PERFORM(); 1502 1503 } 1504 1505 /* 1506 * Class: com_sun_glass_ui_win_WinWindow 1507 * Method: _setTitle 1508 * Signature: (JLjava/lang/String;)Z 1509 */ 1510 JNIEXPORT jboolean JNICALL Java_com_sun_glass_ui_win_WinWindow__1setTitle 1511 (JNIEnv *env, jobject jThis, jlong ptr, jstring jTitle) 1512 { 1513 ENTER_MAIN_THREAD_AND_RETURN(jboolean) 1514 { 1515 if (::SetWindowText(hWnd, title)) { 1516 return JNI_TRUE; 1517 } 1518 return JNI_FALSE; 1519 } 1520 LPCTSTR title; 1521 LEAVE_MAIN_THREAD_WITH_hWnd; 1522 1523 JString title(env, jTitle); 1524 ARG(title) = title; 1525 return PERFORM_AND_RETURN(); 1526 } 1527 1528 /* 1529 * Class: com_sun_glass_ui_win_WinWindow 1530 * Method: _setResizable 1531 * Signature: (Z)Z 1532 */ 1533 JNIEXPORT jboolean JNICALL Java_com_sun_glass_ui_win_WinWindow__1setResizable 1534 (JNIEnv *env, jobject jWindow, jlong ptr, jboolean jResizable) 1535 { 1536 ENTER_MAIN_THREAD_AND_RETURN(jboolean) 1537 { 1538 GlassWindow *pWindow = GlassWindow::FromHandle(hWnd); 1539 if (pWindow && pWindow->SetResizable(jbool_to_bool(jResizable))) { 1540 return JNI_TRUE; 1541 } 1542 1543 return JNI_FALSE; 1544 } 1545 jboolean jResizable; 1546 LEAVE_MAIN_THREAD_WITH_hWnd; 1547 1548 ARG(jResizable) = jResizable; 1549 return PERFORM_AND_RETURN(); 1550 } 1551 1552 /* 1553 * Class: com_sun_glass_ui_win_WinWindow 1554 * Method: _setVisible 1555 * Signature: (JZ)Z 1556 */ 1557 JNIEXPORT jboolean JNICALL Java_com_sun_glass_ui_win_WinWindow__1setVisible 1558 (JNIEnv *env, jobject jThis, jlong ptr, jboolean visible) 1559 { 1560 ENTER_MAIN_THREAD() 1561 { 1562 GlassWindow *pWindow = GlassWindow::FromHandle(hWnd); 1563 if (!visible) { 1564 if (pWindow) { 1565 pWindow->UngrabFocus(); 1566 } 1567 } 1568 1569 ::ShowWindow(hWnd, visible ? SW_SHOW : SW_HIDE); 1570 1571 if (visible) { 1572 if (pWindow) { 1573 if (pWindow->IsFocusable()) { 1574 ::SetForegroundWindow(hWnd); 1575 } else { 1576 // RT-14197: 1577 // On some latest platform versions, unfocusable windows 1578 // are shown below the currently active window, so we 1579 // need to pull them to front explicitly. However, 1580 // neither BringWindowToTop nor SetForegroundWindow() 1581 // can be used because of the window unfocusability, so 1582 // here is a workaround: we first made the window TOPMOST 1583 // and then reset this flag to just TOP. 1584 ::SetWindowPos(hWnd, HWND_TOPMOST, 0, 0, 0, 0, 1585 SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE); 1586 ::SetWindowPos(hWnd, HWND_TOP, 0, 0, 0, 0, 1587 SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE); 1588 } 1589 } 1590 ::UpdateWindow(hWnd); 1591 } 1592 } 1593 jboolean visible; 1594 LEAVE_MAIN_THREAD_WITH_hWnd; 1595 1596 ARG(visible) = visible; 1597 PERFORM(); 1598 return visible; 1599 } 1600 1601 /* 1602 * Class: com_sun_glass_ui_win_WinWindow 1603 * Method: _requestFocus 1604 * Signature: (JI)Z 1605 */ 1606 JNIEXPORT jboolean JNICALL Java_com_sun_glass_ui_win_WinWindow__1requestFocus 1607 (JNIEnv *env, jobject jThis, jlong ptr, jint event) 1608 { 1609 ENTER_MAIN_THREAD_AND_RETURN(jboolean) 1610 { 1611 GlassWindow *pWindow = GlassWindow::FromHandle(hWnd); 1612 return bool_to_jbool(pWindow && pWindow->RequestFocus(event)); 1613 } 1614 jint event; 1615 LEAVE_MAIN_THREAD_WITH_hWnd; 1616 1617 ARG(event) = event; 1618 1619 return PERFORM_AND_RETURN(); 1620 } 1621 1622 /* 1623 * Class: com_sun_glass_ui_win_WinWindow 1624 * Method: _grabFocus 1625 * Signature: (J)Z 1626 */ 1627 JNIEXPORT jboolean JNICALL Java_com_sun_glass_ui_win_WinWindow__1grabFocus 1628 (JNIEnv *env, jobject jThis, jlong ptr) 1629 { 1630 ENTER_MAIN_THREAD_AND_RETURN(jboolean) 1631 { 1632 GlassWindow *pWindow = GlassWindow::FromHandle(hWnd); 1633 return bool_to_jbool(pWindow && pWindow->GrabFocus()); 1634 } 1635 LEAVE_MAIN_THREAD_WITH_hWnd; 1636 1637 return PERFORM_AND_RETURN(); 1638 } 1639 1640 /* 1641 * Class: com_sun_glass_ui_win_WinWindow 1642 * Method: _ungrabFocus 1643 * Signature: (J)V 1644 */ 1645 JNIEXPORT void JNICALL Java_com_sun_glass_ui_win_WinWindow__1ungrabFocus 1646 (JNIEnv *env, jobject jThis, jlong ptr) 1647 { 1648 ENTER_MAIN_THREAD() 1649 { 1650 GlassWindow *pWindow = GlassWindow::FromHandle(hWnd); 1651 if (pWindow) { 1652 pWindow->UngrabFocus(); 1653 } 1654 } 1655 LEAVE_MAIN_THREAD_WITH_hWnd; 1656 1657 PERFORM(); 1658 } 1659 1660 /* 1661 * Class: com_sun_glass_ui_win_WinWindow 1662 * Method: _minimize 1663 * Signature: (JZ)Z 1664 */ 1665 JNIEXPORT jboolean JNICALL Java_com_sun_glass_ui_win_WinWindow__1minimize 1666 (JNIEnv *env, jobject jThis, jlong ptr, jboolean minimize) 1667 { 1668 ENTER_MAIN_THREAD() 1669 { 1670 ::ShowWindow(hWnd, minimize ? SW_MINIMIZE : SW_RESTORE); 1671 } 1672 jboolean minimize; 1673 LEAVE_MAIN_THREAD_WITH_hWnd; 1674 1675 ARG(minimize) = minimize; 1676 PERFORM(); 1677 1678 return JNI_TRUE; 1679 } 1680 1681 /* 1682 * Class: com_sun_glass_ui_win_WinWindow 1683 * Method: _maximize 1684 * Signature: (JZ)Z 1685 */ 1686 JNIEXPORT jboolean JNICALL Java_com_sun_glass_ui_win_WinWindow__1maximize 1687 (JNIEnv *env, jobject jThis, jlong ptr, jboolean maximize, jboolean wasMaximized) 1688 { 1689 ENTER_MAIN_THREAD() 1690 { 1691 ::ShowWindow(hWnd, maximize ? SW_MAXIMIZE : SW_RESTORE); 1692 } 1693 jboolean maximize; 1694 LEAVE_MAIN_THREAD_WITH_hWnd; 1695 1696 ARG(maximize) = maximize; 1697 PERFORM(); 1698 1699 return JNI_TRUE; 1700 } 1701 1702 /* 1703 * Class: com_sun_glass_ui_win_WinWindow 1704 * Method: _setMinimumSize 1705 * Signature: (JII)Z 1706 */ 1707 JNIEXPORT jboolean JNICALL Java_com_sun_glass_ui_win_WinWindow__1setMinimumSize 1708 (JNIEnv *env, jobject jThis, jlong ptr, jint minWidth, jint minHeight) 1709 { 1710 ENTER_MAIN_THREAD_AND_RETURN(jboolean) 1711 { 1712 GlassWindow *pWindow = GlassWindow::FromHandle(hWnd); 1713 if (pWindow) { 1714 pWindow->setMinSize(minWidth, minHeight); 1715 return JNI_TRUE; 1716 } 1717 return JNI_FALSE; 1718 } 1719 jint minWidth; 1720 jint minHeight; 1721 LEAVE_MAIN_THREAD_WITH_hWnd; 1722 1723 ARG(minWidth) = minWidth == 0 ? -1 : minWidth; 1724 ARG(minHeight) = minHeight == 0 ? -1 : minHeight; 1725 return PERFORM_AND_RETURN(); 1726 } 1727 1728 /* 1729 * Class: com_sun_glass_ui_win_WinWindow 1730 * Method: _setMaximumSize 1731 * Signature: (JII)Z 1732 */ 1733 JNIEXPORT jboolean JNICALL Java_com_sun_glass_ui_win_WinWindow__1setMaximumSize 1734 (JNIEnv *env, jobject jThis, jlong ptr, jint maxWidth, jint maxHeight) 1735 { 1736 ENTER_MAIN_THREAD_AND_RETURN(jboolean) 1737 { 1738 GlassWindow *pWindow = GlassWindow::FromHandle(hWnd); 1739 if (pWindow) { 1740 pWindow->setMaxSize(maxWidth, maxHeight); 1741 return JNI_TRUE; 1742 } 1743 return JNI_FALSE; 1744 } 1745 jint maxWidth; 1746 jint maxHeight; 1747 LEAVE_MAIN_THREAD_WITH_hWnd; 1748 1749 ARG(maxWidth) = maxWidth; 1750 ARG(maxHeight) = maxHeight; 1751 return PERFORM_AND_RETURN(); 1752 } 1753 1754 /* 1755 * Class: com_sun_glass_ui_win_WinWindow 1756 * Method: _setIcon 1757 * Signature: (JLcom/sun/glass/ui/Pixels;)V 1758 */ 1759 JNIEXPORT void JNICALL Java_com_sun_glass_ui_win_WinWindow__1setIcon 1760 (JNIEnv *env, jobject jThis, jlong ptr, jobject jPixels) 1761 { 1762 HWND hWnd = (HWND)ptr; 1763 GlassWindow *pWindow = GlassWindow::FromHandle(hWnd); 1764 if (pWindow) { 1765 pWindow->SetIcon(!jPixels ? NULL : Pixels::CreateIcon(env, jPixels)); 1766 } 1767 } 1768 1769 /* 1770 * Class: com_sun_glass_ui_win_WinWindow 1771 * Method: _toFront 1772 * Signature: (J)V 1773 */ 1774 JNIEXPORT void JNICALL Java_com_sun_glass_ui_win_WinWindow__1toFront 1775 (JNIEnv *env, jobject jThis, jlong ptr) 1776 { 1777 ENTER_MAIN_THREAD() 1778 { 1779 GlassWindow *pWindow = GlassWindow::FromHandle(hWnd); 1780 // See comment in __1setVisible() above about unfocusable windows 1781 if (pWindow && !pWindow->IsFocusable()) { 1782 ::SetWindowPos(hWnd, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE); 1783 } 1784 ::SetWindowPos(hWnd, HWND_TOP, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE); 1785 } 1786 LEAVE_MAIN_THREAD_WITH_hWnd; 1787 1788 PERFORM(); 1789 } 1790 1791 /* 1792 * Class: com_sun_glass_ui_win_WinWindow 1793 * Method: _toBack 1794 * Signature: (J)V 1795 */ 1796 JNIEXPORT void JNICALL Java_com_sun_glass_ui_win_WinWindow__1toBack 1797 (JNIEnv *env, jobject jThis, jlong ptr) 1798 { 1799 ENTER_MAIN_THREAD() 1800 { 1801 ::SetWindowPos(hWnd, HWND_BOTTOM, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE); 1802 } 1803 LEAVE_MAIN_THREAD_WITH_hWnd; 1804 1805 PERFORM(); 1806 } 1807 1808 /* 1809 * Class: com_sun_glass_ui_win_WinWindow 1810 * Method: _getEmbeddedX 1811 * Signature: (J)I 1812 */ 1813 JNIEXPORT jint JNICALL Java_com_sun_glass_ui_win_WinWindow__1getEmbeddedX 1814 (JNIEnv *env, jobject jThis, jlong ptr) 1815 { 1816 ENTER_MAIN_THREAD_AND_RETURN(jint) 1817 { 1818 GlassWindow *pWindow = GlassWindow::FromHandle(hWnd); 1819 HWND delegateHWnd = pWindow ? pWindow->GetDelegateWindow() : 0; 1820 RECT rect = {0}; 1821 ::MapWindowPoints(delegateHWnd ? delegateHWnd : hWnd, (HWND)NULL, (LPPOINT)&rect, (sizeof(RECT)/sizeof(POINT))); 1822 return rect.left; 1823 } 1824 LEAVE_MAIN_THREAD_WITH_hWnd; 1825 1826 return PERFORM_AND_RETURN(); 1827 } 1828 1829 /* 1830 * Class: com_sun_glass_ui_win_WinWindow 1831 * Method: _getEmbeddedY 1832 * Signature: (J)I 1833 */ 1834 JNIEXPORT jint JNICALL Java_com_sun_glass_ui_win_WinWindow__1getEmbeddedY 1835 (JNIEnv *env, jobject jThis, jlong ptr) 1836 { 1837 ENTER_MAIN_THREAD_AND_RETURN(jint) 1838 { 1839 GlassWindow *pWindow = GlassWindow::FromHandle(hWnd); 1840 HWND delegateHWnd = pWindow ? pWindow->GetDelegateWindow() : 0; 1841 RECT rect = {0}; 1842 ::MapWindowPoints(delegateHWnd ? delegateHWnd : hWnd, (HWND)NULL, (LPPOINT)&rect, (sizeof(RECT)/sizeof(POINT))); 1843 return rect.top; 1844 } 1845 LEAVE_MAIN_THREAD_WITH_hWnd; 1846 1847 return PERFORM_AND_RETURN(); 1848 } 1849 1850 /* 1851 * Class: com_sun_glass_ui_win_WinWindow 1852 * Method: _setCursor 1853 * Signature: (Lcom/sun/glass/ui/Cursor;)V 1854 */ 1855 JNIEXPORT void JNICALL Java_com_sun_glass_ui_win_WinWindow__1setCursor 1856 (JNIEnv *env, jobject jThis, jlong ptr, jobject jCursor) 1857 { 1858 ENTER_MAIN_THREAD() 1859 { 1860 const HCURSOR cursor = JCursorToHCURSOR(GetEnv(), jCursor); 1861 1862 GlassWindow *pWindow = GlassWindow::FromHandle(hWnd); 1863 if (pWindow) { 1864 pWindow->SetCursor(cursor); 1865 1866 // Update the delegate window as well if present 1867 HWND delegateHwnd = pWindow->GetDelegateWindow(); 1868 if (delegateHwnd) { 1869 BaseWnd *pDelegateWindow = BaseWnd::FromHandle(delegateHwnd); 1870 if (pDelegateWindow) { 1871 pDelegateWindow->SetCursor(cursor); 1872 } 1873 } 1874 } 1875 } 1876 DECL_jobject(jCursor); 1877 LEAVE_MAIN_THREAD_WITH_hWnd; 1878 1879 ARG(jCursor) = jCursor; 1880 PERFORM(); 1881 } 1882 1883 } // extern "C"