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