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 UINT xDPI = LOWORD(wParam); 651 UINT yDPI = HIWORD(wParam); 652 653 // fprintf(stderr, "DPI Changed (=> %d, %d)!\n", yDPI, xDPI); 654 JNIEnv* env = GetEnv(); 655 jfloat newUIScale = GlassApplication::GetUIScale(xDPI); 656 jfloat newRenderScale = GlassApplication::getRenderScale(newUIScale); 657 env->CallVoidMethod(m_grefThis, midNotifyScaleChanged, newUIScale, newRenderScale); 658 CheckAndClearException(env); 659 660 LPRECT lprcNewScale = (LPRECT) lParam; 661 #if 0 662 RECT oldBounds, oldClient; 663 ::GetWindowRect(GetHWND(), &oldBounds); 664 ::GetClientRect(GetHWND(), &oldClient); 665 POINT cursor; 666 ::GetCursorPos(&cursor); 667 fprintf(stderr, " @ %d, %d\n", cursor.x, cursor.y); 668 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", 669 oldClient.left, oldClient.top, oldClient.right, oldClient.bottom, 670 oldClient.right - oldClient.left, oldClient.bottom - oldClient.top, 671 oldBounds.left, oldBounds.top, oldBounds.right, oldBounds.bottom, 672 oldBounds.right - oldBounds.left, oldBounds.bottom - oldBounds.top, 673 lprcNewScale->left, lprcNewScale->top, lprcNewScale->right, lprcNewScale->bottom, 674 lprcNewScale->right - lprcNewScale->left, lprcNewScale->bottom - lprcNewScale->top); 675 #endif 676 ::SetWindowPos(GetHWND(), HWND_TOP, 677 lprcNewScale->left, 678 lprcNewScale->top, 679 lprcNewScale->right - lprcNewScale->left, 680 lprcNewScale->bottom - lprcNewScale->top, 681 SWP_NOZORDER | SWP_NOACTIVATE); 682 } 683 684 void GlassWindow::HandleWindowPosChangedEvent() 685 { 686 JNIEnv* env = GetEnv(); 687 688 HMONITOR toMonitor = ::MonitorFromWindow(GetHWND(), MONITOR_DEFAULTTOPRIMARY); 689 HMONITOR fromMonitor = GetMonitor(); 690 if (toMonitor != fromMonitor) { 691 // fprintf(stderr, "Monitor changed!\n"); 692 env->CallVoidMethod(m_grefThis, midNotifyMoveToAnotherScreen, 693 GlassScreen::GetJavaMonitor(env, toMonitor)); 694 CheckAndClearException(env); 695 SetMonitor(toMonitor); 696 } 697 } 698 699 void GlassWindow::HandleActivateEvent(jint event) 700 { 701 const bool active = event != com_sun_glass_events_WindowEvent_FOCUS_LOST; 702 703 if (!active) { 704 UngrabFocus(); 705 } 706 707 JNIEnv* env = GetEnv(); 708 env->CallVoidMethod(m_grefThis, javaIDs.Window.notifyFocus, event); 709 CheckAndClearException(env); 710 } 711 712 void GlassWindow::HandleFocusDisabledEvent() 713 { 714 JNIEnv* env = GetEnv(); 715 716 env->CallVoidMethod(m_grefThis, javaIDs.Window.notifyFocusDisabled); 717 CheckAndClearException(env); 718 } 719 720 bool GlassWindow::HandleCommand(WORD cmdID) { 721 return HandleMenuCommand(GetHWND(), cmdID); 722 } 723 724 HMONITOR GlassWindow::GetMonitor() 725 { 726 return m_hMonitor; 727 } 728 729 void GlassWindow::SetMonitor(HMONITOR hMonitor) 730 { 731 m_hMonitor = hMonitor; 732 } 733 734 void GlassWindow::SetAlpha(BYTE alpha) 735 { 736 m_alpha = alpha; 737 738 if (m_isTransparent) { 739 // If the window is transparent, the opacity is handled in 740 // uploadPixels() below (see BLENDFUNCTION structure 741 // and its SourceConstantAlpha member) 742 return; 743 } 744 745 // The window is opaque. We make it layered temporarily only when 746 // its alpha is less than 0xFF. 747 LONG exStyle = ::GetWindowLong(GetHWND(), GWL_EXSTYLE); 748 749 if (alpha == 0xFF) { 750 if (exStyle & WS_EX_LAYERED) { 751 ::SetWindowLong(GetHWND(), GWL_EXSTYLE, exStyle & ~WS_EX_LAYERED); 752 } 753 } else { 754 if (!(exStyle & WS_EX_LAYERED)) { 755 ::SetWindowLong(GetHWND(), GWL_EXSTYLE, exStyle | WS_EX_LAYERED); 756 } 757 ::SetLayeredWindowAttributes(GetHWND(), RGB(0, 0, 0), alpha, LWA_ALPHA); 758 } 759 } 760 761 void GlassWindow::UpdateInsets() 762 { 763 if (::IsIconic(GetHWND())) { 764 return; 765 } 766 767 RECT outer, inner; 768 769 ::GetWindowRect(GetHWND(), &outer); 770 ::GetClientRect(GetHWND(), &inner); 771 772 ::MapWindowPoints(GetHWND(), (HWND)NULL, (LPPOINT)&inner, (sizeof(RECT)/sizeof(POINT))); 773 774 m_insets.top = inner.top - outer.top; 775 m_insets.left = inner.left - outer.left; 776 m_insets.bottom = outer.bottom - inner.bottom; 777 m_insets.right = outer.right - inner.right; 778 779 if (m_insets.top < 0 || m_insets.left < 0 || 780 m_insets.bottom < 0 || m_insets.right < 0) 781 { 782 if (!IsDecorated()) { 783 ::ZeroMemory(&m_insets, sizeof(m_insets)); 784 } else { 785 if (GetStyle() & WS_THICKFRAME) { 786 m_insets.left = m_insets.right = 787 ::GetSystemMetrics(SM_CXSIZEFRAME); 788 m_insets.top = m_insets.bottom = 789 ::GetSystemMetrics(SM_CYSIZEFRAME); 790 } else { 791 m_insets.left = m_insets.right = 792 ::GetSystemMetrics(SM_CXDLGFRAME); 793 m_insets.top = m_insets.bottom = 794 ::GetSystemMetrics(SM_CYDLGFRAME); 795 } 796 797 m_insets.top += ::GetSystemMetrics(SM_CYCAPTION); 798 } 799 if (GetMenu()) { 800 //Well, if menu wraps on multiple lines... sorry about that. 801 m_insets.top += ::GetSystemMetrics(SM_CYMENU); 802 } 803 } 804 } 805 806 bool GlassWindow::SetResizable(bool resizable) 807 { 808 LONG style = GetStyle(); 809 810 if (style & WS_CHILD) { 811 return false; 812 } 813 814 LONG resizableStyle = WS_MAXIMIZEBOX; 815 if (IsDecorated()) { 816 resizableStyle |= WS_THICKFRAME; 817 } 818 819 if (resizable) { 820 style |= resizableStyle; 821 } else { 822 style &= ~resizableStyle; 823 } 824 825 SetStyle(style); 826 m_isResizable = resizable; 827 828 return true; 829 } 830 831 /* static */ void GlassWindow::ResetGrab() 832 { 833 if (sm_grabWindow) { 834 GlassWindow *pWindow = GlassWindow::FromHandle(sm_grabWindow); 835 if (pWindow) { 836 pWindow->UngrabFocus(); 837 } 838 sm_grabWindow = NULL; 839 } 840 } 841 842 bool GlassWindow::GrabFocus() 843 { 844 HWND hwnd = GetCurrentHWND(); 845 846 if (sm_grabWindow == hwnd) { 847 // Already grabbed 848 return true; 849 } 850 851 GlassWindow::ResetGrab(); 852 853 sm_grabWindow = hwnd; 854 855 return true; 856 } 857 858 void GlassWindow::UngrabFocus() 859 { 860 HWND hwnd = GetCurrentHWND(); 861 862 if (hwnd != sm_grabWindow) { 863 return; 864 } 865 866 JNIEnv* env = GetEnv(); 867 env->CallVoidMethod(m_grefThis, javaIDs.Window.notifyFocusUngrab); 868 CheckAndClearException(env); 869 870 sm_grabWindow = NULL; 871 } 872 873 void GlassWindow::CheckUngrab() 874 { 875 if (!sm_grabWindow) { 876 return; 877 } 878 879 // If this window doesn't belong to an owned windows hierarchy that 880 // holds the grab currently, then the grab should be released. 881 // Fix RT-16490: use GetAncestor() instead of ::GetParent() to support embedded windows 882 for (BaseWnd * window = this; window != NULL; window = BaseWnd::FromHandle(window->GetAncestor())) { 883 if (window->GetHWND() == sm_grabWindow) { 884 return; 885 } 886 } 887 888 GlassWindow::ResetGrab(); 889 } 890 891 bool GlassWindow::RequestFocus(jint event) 892 { 893 if (!IsChild()) { 894 ASSERT(event == com_sun_glass_events_WindowEvent_FOCUS_GAINED); 895 // The event will be delivered as a part of WM_ACTIVATE message handling 896 return ::SetForegroundWindow(GetHWND()) != FALSE; 897 } 898 899 if (event == com_sun_glass_events_WindowEvent_FOCUS_LOST) { 900 if (IsFocused()) { 901 ::SetFocus(NULL); 902 } 903 904 return true; 905 } 906 907 // First try to activate the toplevel window 908 HWND toplevel = ::GetAncestor(GetHWND(), GA_ROOT); 909 if (::GetForegroundWindow() != toplevel && !::SetForegroundWindow(toplevel)) { 910 // We're unable to bring our top-level window to foreground. 911 // But since it anyway becomes active, we (or the plugin) won't receive 912 // any subsequent notifications. So let's pretend we got the focus - 913 //IGNORE: return false; 914 //We'll anyway get a reasonable response from the ::SetFocus() later 915 } 916 917 m_focusEvent = event; // reset upon WM_SETFOCUS 918 919 // If we request focus from 'nowhere', the SetFocus may still return NULL I guess 920 return ::SetFocus(GetHWND()) != NULL || ::GetLastError() == 0; 921 } 922 923 static BOOL CALLBACK EnumChildWndProc(HWND hwnd, LPARAM lParam) 924 { 925 HWND * hwnds = (HWND*)lParam; 926 927 ::SetParent(hwnd, hwnds[1]); 928 929 BaseWnd * window = BaseWnd::FromHandle(hwnd); 930 if (window) { 931 window->SetAncestor(hwnds[1]); 932 } 933 934 return TRUE; 935 } 936 937 static BOOL CALLBACK EnumOwnedWndProc(HWND hwnd, LPARAM lParam) 938 { 939 HWND * hwnds = (HWND*)lParam; 940 941 GlassWindow * window = NULL; 942 if ((HWND)::GetWindowLongPtr(hwnd, GWLP_HWNDPARENT) == hwnds[0] && (window = GlassWindow::FromHandle(hwnd)) != NULL) { 943 ::SetWindowLongPtr(hwnd, GWLP_HWNDPARENT, (LONG_PTR)hwnds[1]); 944 window->SetAncestor(hwnds[1]); 945 ::SetWindowPos(hwnd, hwnds[1], 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_FRAMECHANGED | SWP_NOACTIVATE); 946 } 947 948 return TRUE; 949 } 950 951 void GlassWindow::SetDelegateWindow(HWND hWnd) 952 { 953 if (m_delegateWindow == hWnd) { 954 return; 955 } 956 957 // Make sure any popups are hidden 958 UngrabFocus(); 959 960 HWND hwnds[2]; // [0] = from; [1] = to; 961 962 hwnds[0] = m_delegateWindow ? m_delegateWindow : GetHWND(); 963 hwnds[1] = hWnd ? hWnd : GetHWND(); 964 965 STRACE(_T("SetDelegateWindow: from %p to %p"), hwnds[0], hwnds[1]); 966 967 // Reparent child, and then owned windows 968 ::EnumChildWindows(hwnds[0], &EnumChildWndProc, (LPARAM)&hwnds); 969 ::EnumThreadWindows(GlassApplication::GetMainThreadId(), &EnumOwnedWndProc, (LPARAM)&hwnds); 970 971 m_delegateWindow = hWnd; 972 973 GetEnv()->CallVoidMethod(m_grefThis, 974 javaIDs.Window.notifyDelegatePtr, (jlong)hWnd); 975 CheckAndClearException(GetEnv()); 976 } 977 978 BOOL GlassWindow::EnterFullScreenMode(GlassView * view, BOOL animate, BOOL keepRatio) 979 { 980 if (IsChild()) { 981 return FALSE; 982 } 983 if (IsInFullScreenMode()) { 984 return TRUE; 985 } 986 if (view != GetGlassView()) { 987 STRACE(_T("EnterFullScreenMode(view = %p) while the real view for this window is: %p"), view, GetGlassView()); 988 return FALSE; 989 } 990 991 static const LONG FS_STYLE_MASK = WS_CAPTION | WS_MINIMIZEBOX | WS_MAXIMIZEBOX | WS_BORDER | WS_THICKFRAME; 992 static const LONG FS_EXSTYLE_MASK = WS_EX_WINDOWEDGE; 993 994 LONG style = ::GetWindowLong(GetHWND(), GWL_STYLE); 995 LONG exStyle = ::GetWindowLong(GetHWND(), GWL_EXSTYLE); 996 997 ::GetWindowRect(GetHWND(), &m_beforeFullScreenRect); 998 m_beforeFullScreenStyle = style & FS_STYLE_MASK; 999 m_beforeFullScreenExStyle = exStyle & FS_EXSTYLE_MASK; 1000 m_beforeFullScreenMenu = ::GetMenu(GetHWND()); 1001 1002 RECT viewRect, screenRect, contentRect; 1003 1004 FullScreenWindow::ClientRectInScreen(GetHWND(), &viewRect); 1005 FullScreenWindow::CalculateBounds(GetHWND(), &screenRect, 1006 &contentRect, keepRatio, viewRect); 1007 1008 //XXX: if (keepRatio) initBlackBackground(screenRect); 1009 1010 ::SetWindowLong(GetHWND(), GWL_STYLE, style & ~FS_STYLE_MASK); 1011 ::SetWindowLong(GetHWND(), GWL_EXSTYLE, exStyle & ~FS_EXSTYLE_MASK); 1012 1013 ::SetMenu(GetHWND(), NULL); 1014 1015 ::SetWindowPos(GetHWND(), HWND_TOPMOST, 1016 contentRect.left, contentRect.top, 1017 contentRect.right - contentRect.left, contentRect.bottom - contentRect.top, 1018 SWP_FRAMECHANGED | SWP_NOCOPYBITS); 1019 1020 m_isInFullScreen = true; 1021 1022 return TRUE; 1023 } 1024 1025 void GlassWindow::ExitFullScreenMode(BOOL animate) 1026 { 1027 if (IsChild() || !IsInFullScreenMode()) { 1028 return; 1029 } 1030 1031 LONG style = ::GetWindowLong(GetHWND(), GWL_STYLE); 1032 LONG exStyle = ::GetWindowLong(GetHWND(), GWL_EXSTYLE); 1033 1034 ::SetWindowLong(GetHWND(), GWL_STYLE, style | m_beforeFullScreenStyle); 1035 ::SetWindowLong(GetHWND(), GWL_EXSTYLE, exStyle | m_beforeFullScreenExStyle); 1036 1037 ::SetMenu(GetHWND(), m_beforeFullScreenMenu); 1038 1039 LONG swpFlags = SWP_FRAMECHANGED | SWP_NOCOPYBITS; 1040 if (!IsFocused()) { 1041 swpFlags |= SWP_NOACTIVATE; 1042 } 1043 ::SetWindowPos(GetHWND(), HWND_NOTOPMOST, 1044 m_beforeFullScreenRect.left, m_beforeFullScreenRect.top, 1045 m_beforeFullScreenRect.right - m_beforeFullScreenRect.left, 1046 m_beforeFullScreenRect.bottom - m_beforeFullScreenRect.top, 1047 swpFlags); 1048 1049 m_isInFullScreen = false; 1050 } 1051 1052 void GlassWindow::SetEnabled(bool enabled) 1053 { 1054 if (!enabled) { 1055 ResetMouseTracking(GetHWND()); 1056 } 1057 1058 m_isEnabled = enabled; 1059 } 1060 1061 void GlassWindow::SetIcon(HICON hIcon) 1062 { 1063 ::SendMessage(GetHWND(), WM_SETICON, ICON_SMALL, (LPARAM)hIcon); 1064 ::SendMessage(GetHWND(), WM_SETICON, ICON_BIG, (LPARAM)hIcon); 1065 1066 if (m_hIcon) { 1067 ::DestroyIcon(m_hIcon); 1068 } 1069 m_hIcon = hIcon; 1070 } 1071 1072 /* 1073 * JNI methods section 1074 * 1075 */ 1076 1077 extern "C" { 1078 1079 /* 1080 * Class: com_sun_glass_ui_win_WinWindow 1081 * Method: _initIDs 1082 * Signature: ()V 1083 */ 1084 JNIEXPORT void JNICALL Java_com_sun_glass_ui_win_WinWindow__1initIDs 1085 (JNIEnv *env, jclass cls) 1086 { 1087 midNotifyClose = env->GetMethodID(cls, "notifyClose", "()V"); 1088 ASSERT(midNotifyClose); 1089 if (env->ExceptionCheck()) return; 1090 1091 midNotifyMove = env->GetMethodID(cls, "notifyMove", "(II)V"); 1092 ASSERT(midNotifyMove); 1093 if (env->ExceptionCheck()) return; 1094 1095 midNotifyResize = env->GetMethodID(cls, "notifyResize", "(III)V"); 1096 ASSERT(midNotifyResize); 1097 if (env->ExceptionCheck()) return; 1098 1099 midNotifyScaleChanged = env->GetMethodID(cls, "notifyScaleChanged", "(FF)V"); 1100 ASSERT(midNotifyScaleChanged); 1101 if (env->ExceptionCheck()) return; 1102 1103 javaIDs.Window.notifyFocus = env->GetMethodID(cls, "notifyFocus", "(I)V"); 1104 ASSERT(javaIDs.Window.notifyFocus); 1105 if (env->ExceptionCheck()) return; 1106 1107 javaIDs.Window.notifyFocusDisabled = env->GetMethodID(cls, "notifyFocusDisabled", "()V"); 1108 ASSERT(javaIDs.Window.notifyFocusDisabled); 1109 if (env->ExceptionCheck()) return; 1110 1111 javaIDs.Window.notifyFocusUngrab = env->GetMethodID(cls, "notifyFocusUngrab", "()V"); 1112 ASSERT(javaIDs.Window.notifyFocusUngrab); 1113 if (env->ExceptionCheck()) return; 1114 1115 midNotifyMoveToAnotherScreen = env->GetMethodID(cls, "notifyMoveToAnotherScreen", "(Lcom/sun/glass/ui/Screen;)V"); 1116 ASSERT(midNotifyMoveToAnotherScreen); 1117 if (env->ExceptionCheck()) return; 1118 1119 javaIDs.Window.notifyDestroy = env->GetMethodID(cls, "notifyDestroy", "()V"); 1120 ASSERT(javaIDs.Window.notifyDestroy); 1121 if (env->ExceptionCheck()) return; 1122 1123 javaIDs.Window.notifyDelegatePtr = env->GetMethodID(cls, "notifyDelegatePtr", "(J)V"); 1124 ASSERT(javaIDs.Window.notifyDelegatePtr); 1125 if (env->ExceptionCheck()) return; 1126 } 1127 1128 /* 1129 * Class: com_sun_glass_ui_win_WinWindow 1130 * Method: _createWindow 1131 * Signature: (JJZI)J 1132 */ 1133 JNIEXPORT jlong JNICALL Java_com_sun_glass_ui_win_WinWindow__1createWindow 1134 (JNIEnv *env, jobject jThis, jlong ownerPtr, jlong screenPtr, jint mask) 1135 { 1136 ENTER_MAIN_THREAD_AND_RETURN(jlong) 1137 { 1138 DWORD dwStyle; 1139 DWORD dwExStyle; 1140 bool closeable; 1141 1142 dwStyle = WS_CLIPCHILDREN | WS_SYSMENU; 1143 closeable = (mask & com_sun_glass_ui_Window_CLOSABLE) != 0; 1144 1145 if (mask & com_sun_glass_ui_Window_TITLED) { 1146 dwExStyle = WS_EX_WINDOWEDGE; 1147 dwStyle |= WS_CAPTION; 1148 1149 if (mask & com_sun_glass_ui_Window_MINIMIZABLE) { 1150 dwStyle |= WS_MINIMIZEBOX; 1151 } 1152 if (mask & com_sun_glass_ui_Window_MAXIMIZABLE) { 1153 dwStyle |= WS_MAXIMIZEBOX; 1154 } 1155 } else { 1156 dwExStyle = 0; 1157 dwStyle |= WS_POPUP; 1158 } 1159 1160 if (mask & com_sun_glass_ui_Window_TRANSPARENT) { 1161 dwExStyle |= WS_EX_LAYERED; 1162 } 1163 1164 if (mask & com_sun_glass_ui_Window_POPUP) { 1165 dwStyle |= WS_POPUP; 1166 // Popups should not appear in the taskbar, so WS_EX_TOOLWINDOW 1167 dwExStyle |= WS_EX_TOOLWINDOW; 1168 } 1169 1170 if (mask & com_sun_glass_ui_Window_UTILITY) { 1171 dwExStyle |= WS_EX_TOOLWINDOW; 1172 } 1173 1174 if (mask & com_sun_glass_ui_Window_RIGHT_TO_LEFT) { 1175 dwExStyle |= WS_EX_NOINHERITLAYOUT | WS_EX_LAYOUTRTL; 1176 } 1177 1178 GlassWindow *pWindow = 1179 new GlassWindow(jThis, 1180 (mask & com_sun_glass_ui_Window_TRANSPARENT) != 0, 1181 (mask & com_sun_glass_ui_Window_TITLED) != 0, 1182 (mask & com_sun_glass_ui_Window_UNIFIED) != 0, 1183 false, 1184 owner); 1185 1186 HWND hWnd = pWindow->Create(dwStyle, dwExStyle, hMonitor, owner); 1187 1188 if (!hWnd) { 1189 delete pWindow; 1190 } else { 1191 if (!closeable) { 1192 HMENU hSysMenu = ::GetSystemMenu(hWnd, FALSE); 1193 if (hSysMenu != NULL) { 1194 ::EnableMenuItem(hSysMenu, SC_CLOSE, 1195 MF_BYCOMMAND | MF_DISABLED | MF_GRAYED); 1196 } 1197 } 1198 } 1199 1200 return (jlong)hWnd; 1201 } 1202 DECL_jobject(jThis); 1203 HWND owner; 1204 HMONITOR hMonitor; 1205 jint mask; 1206 LEAVE_MAIN_THREAD; 1207 1208 ARG(jThis) = jThis; 1209 ARG(owner) = (HWND)ownerPtr; 1210 ARG(hMonitor) = (HMONITOR)screenPtr; 1211 ARG(mask) = mask; 1212 1213 return PERFORM_AND_RETURN(); 1214 } 1215 1216 /* 1217 * Class: com_sun_glass_ui_win_WinWindow 1218 * Method: _createChildWindow 1219 * Signature: (J)J 1220 */ 1221 JNIEXPORT jlong JNICALL Java_com_sun_glass_ui_win_WinWindow__1createChildWindow 1222 (JNIEnv *env, jobject jThis, jlong parentPtr) 1223 { 1224 ENTER_MAIN_THREAD_AND_RETURN(jlong) 1225 { 1226 // Check that the 'parent' isn't a garbage value 1227 if (!::IsWindow((HWND)parent)) { 1228 return (jlong)0; 1229 } 1230 1231 DWORD dwStyle; 1232 DWORD dwExStyle; 1233 1234 dwStyle = WS_CLIPCHILDREN | WS_CLIPSIBLINGS | WS_CHILD; 1235 dwExStyle = WS_EX_NOINHERITLAYOUT; 1236 1237 GlassWindow *pWindow = 1238 new GlassWindow(jThis, false, false, false, true, parent); 1239 1240 HWND hWnd = pWindow->Create(dwStyle, dwExStyle, NULL, parent); 1241 1242 if (!hWnd) { 1243 delete pWindow; 1244 } 1245 pWindow->HandleWindowPosChangedEvent(); 1246 1247 return (jlong)hWnd; 1248 } 1249 DECL_jobject(jThis); 1250 HWND parent; 1251 LEAVE_MAIN_THREAD; 1252 1253 ARG(jThis) = jThis; 1254 ARG(parent) = (HWND)parentPtr; 1255 1256 return PERFORM_AND_RETURN(); 1257 } 1258 /* 1259 * Class: com_sun_glass_ui_win_WinWindow 1260 * Method: _close 1261 * Signature: (J)Z 1262 */ 1263 JNIEXPORT jboolean JNICALL Java_com_sun_glass_ui_win_WinWindow__1close 1264 (JNIEnv *env, jobject jThis, jlong ptr) 1265 { 1266 ENTER_MAIN_THREAD_AND_RETURN(jboolean) 1267 { 1268 GlassWindow *pWindow = GlassWindow::FromHandle(hWnd); 1269 pWindow->Close(); 1270 return bool_to_jbool(::DestroyWindow(hWnd)); 1271 } 1272 LEAVE_MAIN_THREAD_WITH_hWnd; 1273 1274 return PERFORM_AND_RETURN(); 1275 } 1276 1277 /* 1278 * Class: com_sun_glass_ui_win_WinWindow 1279 * Method: _setView 1280 * Signature: (JJ)Z 1281 */ 1282 JNIEXPORT jboolean JNICALL Java_com_sun_glass_ui_win_WinWindow__1setView 1283 (JNIEnv * env, jobject jThis, jlong ptr, jobject view) 1284 { 1285 ENTER_MAIN_THREAD() 1286 { 1287 GlassWindow *pWindow = GlassWindow::FromHandle(hWnd); 1288 1289 if (activeTouchWindow == hWnd) { 1290 activeTouchWindow = 0; 1291 } 1292 pWindow->ResetMouseTracking(hWnd); 1293 pWindow->SetGlassView(view); 1294 // The condition below may be restricted to WS_POPUP windows 1295 if (::IsWindowVisible(hWnd)) { 1296 pWindow->NotifyViewSize(hWnd); 1297 } 1298 } 1299 GlassView * view; 1300 LEAVE_MAIN_THREAD_WITH_hWnd; 1301 1302 ARG(view) = view == NULL ? NULL : (GlassView*)env->GetLongField(view, javaIDs.View.ptr); 1303 1304 PERFORM(); 1305 return JNI_TRUE; 1306 } 1307 1308 /* 1309 * Class: com_sun_glass_ui_win_WinWindow 1310 * Method: _setMenubar 1311 * Signature: (JJ)Z 1312 */ 1313 JNIEXPORT jboolean JNICALL Java_com_sun_glass_ui_win_WinWindow__1setMenubar 1314 (JNIEnv *env, jobject jThis, jlong ptr, jlong menuPtr) 1315 { 1316 ENTER_MAIN_THREAD_AND_RETURN(jboolean) 1317 { 1318 if (::SetMenu(hWnd, hMenu)) 1319 { 1320 GlassWindow *pWindow = GlassWindow::FromHandle(hWnd); 1321 if (pWindow) { 1322 pWindow->SetMenu(hMenu); 1323 } 1324 1325 return JNI_TRUE; 1326 } 1327 return JNI_FALSE; 1328 } 1329 HMENU hMenu; 1330 LEAVE_MAIN_THREAD_WITH_hWnd; 1331 1332 ARG(hMenu) = (HMENU)menuPtr; 1333 return PERFORM_AND_RETURN(); 1334 } 1335 1336 /* 1337 * Class: com_sun_glass_ui_win_WinWindow 1338 * Method: _setLevel 1339 * Signature: (JI)V 1340 */ 1341 JNIEXPORT void JNICALL Java_com_sun_glass_ui_win_WinWindow__1setLevel 1342 (JNIEnv *env, jobject jwindow, jlong ptr, jint jLevel) 1343 { 1344 ENTER_MAIN_THREAD() 1345 { 1346 ::SetWindowPos(hWnd, hWndInsertAfter, 0, 0, 0, 0, 1347 SWP_ASYNCWINDOWPOS | SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOOWNERZORDER | SWP_NOSIZE); 1348 } 1349 HWND hWndInsertAfter; 1350 LEAVE_MAIN_THREAD_WITH_hWnd; 1351 1352 ARG(hWndInsertAfter) = HWND_NOTOPMOST; 1353 switch (jLevel) { 1354 case com_sun_glass_ui_Window_Level_FLOATING: 1355 case com_sun_glass_ui_Window_Level_TOPMOST: 1356 ARG(hWndInsertAfter) = HWND_TOPMOST; 1357 break; 1358 } 1359 PERFORM(); 1360 } 1361 1362 /* 1363 * Class: com_sun_glass_ui_win_WinWindow 1364 * Method: _setFocusable 1365 * Signature: (JZ)V 1366 */ 1367 JNIEXPORT void JNICALL Java_com_sun_glass_ui_win_WinWindow__1setFocusable 1368 (JNIEnv *env, jobject jwindow, jlong ptr, jboolean isFocusable) 1369 { 1370 ENTER_MAIN_THREAD() 1371 { 1372 GlassWindow *pWindow = GlassWindow::FromHandle(hWnd); 1373 pWindow->SetFocusable(isFocusable); 1374 } 1375 bool isFocusable; 1376 LEAVE_MAIN_THREAD_WITH_hWnd; 1377 1378 ARG(isFocusable) = isFocusable == JNI_TRUE; 1379 PERFORM(); 1380 } 1381 1382 /* 1383 * Class: com_sun_glass_ui_win_WinWindow 1384 * Method: _setEnabled 1385 * Signature: (JZ)V 1386 */ 1387 JNIEXPORT void JNICALL Java_com_sun_glass_ui_win_WinWindow__1setEnabled 1388 (JNIEnv *env, jobject jwindow, jlong ptr, jboolean isEnabled) 1389 { 1390 ENTER_MAIN_THREAD() 1391 { 1392 GlassWindow *pWindow = GlassWindow::FromHandle(hWnd); 1393 pWindow->SetEnabled(isEnabled); 1394 ::EnableWindow(hWnd, isEnabled); 1395 } 1396 bool isEnabled; 1397 LEAVE_MAIN_THREAD_WITH_hWnd; 1398 1399 ARG(isEnabled) = isEnabled == JNI_TRUE; 1400 PERFORM(); 1401 } 1402 1403 // Converts a float [0..1] to a BYTE [0..255] 1404 #define F2B(value) BYTE(255.f * (value)) 1405 1406 /* 1407 * Class: com_sun_glass_ui_win_WinWindow 1408 * Method: _setAlpha 1409 * Signature: (JF)V 1410 */ 1411 JNIEXPORT void JNICALL Java_com_sun_glass_ui_win_WinWindow__1setAlpha 1412 (JNIEnv *env, jobject jThis, jlong ptr, jfloat alpha) 1413 { 1414 ENTER_MAIN_THREAD() 1415 { 1416 GlassWindow *pWindow = GlassWindow::FromHandle(hWnd); 1417 pWindow->SetAlpha(alpha); 1418 } 1419 BYTE alpha; 1420 LEAVE_MAIN_THREAD_WITH_hWnd; 1421 1422 ARG(alpha) = F2B(alpha); 1423 PERFORM(); 1424 } 1425 1426 /* 1427 * Class: com_sun_glass_ui_win_WinWindow 1428 * Method: _setBackground 1429 * Signature: (JFFF)Z 1430 */ 1431 JNIEXPORT jboolean JNICALL Java_com_sun_glass_ui_win_WinWindow__1setBackground 1432 (JNIEnv *env, jobject jThis, jlong ptr, jfloat r, jfloat g, jfloat b) 1433 { 1434 ENTER_MAIN_THREAD() 1435 { 1436 HBRUSH hbrBackground; 1437 1438 // That's a hack with 'negative' color 1439 if (r < 0) { 1440 hbrBackground = NULL; 1441 } else { 1442 hbrBackground = ::CreateSolidBrush(RGB(F2B(r), F2B(g), F2B(b))); 1443 } 1444 1445 HBRUSH oldBrush = (HBRUSH)::SetClassLongPtr(hWnd, GCLP_HBRBACKGROUND, (LONG_PTR)hbrBackground); 1446 1447 if (oldBrush) { 1448 ::DeleteObject(oldBrush); 1449 } 1450 } 1451 jfloat r, g, b; 1452 LEAVE_MAIN_THREAD_WITH_hWnd; 1453 1454 ARG(r) = r; 1455 ARG(g) = g; 1456 ARG(b) = b; 1457 PERFORM(); 1458 1459 return JNI_TRUE; 1460 } 1461 1462 /* 1463 * Class: com_sun_glass_ui_win_WinWindow 1464 * Method: _setBounds 1465 * Signature: (JIIZZIIIIFF)Z 1466 */ 1467 JNIEXPORT void JNICALL Java_com_sun_glass_ui_win_WinWindow__1setBounds 1468 (JNIEnv *env, jobject jThis, jlong ptr, 1469 jint x, jint y, jboolean xSet, jboolean ySet, 1470 jint w, jint h, jint cw, jint ch, 1471 jfloat xGravity, jfloat yGravity) 1472 { 1473 ENTER_MAIN_THREAD() 1474 { 1475 if (!::IsWindow(hWnd)) return; 1476 GlassWindow *pWindow = GlassWindow::FromHandle(hWnd); 1477 1478 pWindow->UpdateInsets(); 1479 RECT is = pWindow->GetInsets(); 1480 1481 RECT r; 1482 ::GetWindowRect(hWnd, &r); 1483 1484 int newX = jbool_to_bool(xSet) ? x : r.left; 1485 int newY = jbool_to_bool(ySet) ? y : r.top; 1486 int newW = w > 0 ? w : 1487 cw > 0 ? cw + is.right + is.left : r.right - r.left; 1488 int newH = h > 0 ? h : 1489 ch > 0 ? ch + is.bottom + is.top : r.bottom - r.top; 1490 1491 if (xSet || ySet) { 1492 ::SetWindowPos(hWnd, NULL, newX, newY, newW, newH, 1493 SWP_NOACTIVATE | SWP_NOZORDER); 1494 } else { 1495 ::SetWindowPos(hWnd, NULL, 0, 0, newW, newH, 1496 SWP_NOACTIVATE | SWP_NOZORDER | SWP_NOMOVE); 1497 } 1498 } 1499 jint x, y; 1500 jboolean xSet, ySet; 1501 jint w, h, cw, ch; 1502 LEAVE_MAIN_THREAD_WITH_hWnd; 1503 1504 ARG(x) = x; 1505 ARG(y) = y; 1506 ARG(xSet) = xSet; 1507 ARG(ySet) = ySet; 1508 ARG(w) = w; 1509 ARG(h) = h; 1510 ARG(cw) = cw; 1511 ARG(ch) = ch; 1512 PERFORM(); 1513 1514 } 1515 1516 /* 1517 * Class: com_sun_glass_ui_win_WinWindow 1518 * Method: _setTitle 1519 * Signature: (JLjava/lang/String;)Z 1520 */ 1521 JNIEXPORT jboolean JNICALL Java_com_sun_glass_ui_win_WinWindow__1setTitle 1522 (JNIEnv *env, jobject jThis, jlong ptr, jstring jTitle) 1523 { 1524 ENTER_MAIN_THREAD_AND_RETURN(jboolean) 1525 { 1526 if (::SetWindowText(hWnd, title)) { 1527 return JNI_TRUE; 1528 } 1529 return JNI_FALSE; 1530 } 1531 LPCTSTR title; 1532 LEAVE_MAIN_THREAD_WITH_hWnd; 1533 1534 JString title(env, jTitle); 1535 ARG(title) = title; 1536 return PERFORM_AND_RETURN(); 1537 } 1538 1539 /* 1540 * Class: com_sun_glass_ui_win_WinWindow 1541 * Method: _setResizable 1542 * Signature: (Z)Z 1543 */ 1544 JNIEXPORT jboolean JNICALL Java_com_sun_glass_ui_win_WinWindow__1setResizable 1545 (JNIEnv *env, jobject jWindow, jlong ptr, jboolean jResizable) 1546 { 1547 ENTER_MAIN_THREAD_AND_RETURN(jboolean) 1548 { 1549 GlassWindow *pWindow = GlassWindow::FromHandle(hWnd); 1550 if (pWindow && pWindow->SetResizable(jbool_to_bool(jResizable))) { 1551 return JNI_TRUE; 1552 } 1553 1554 return JNI_FALSE; 1555 } 1556 jboolean jResizable; 1557 LEAVE_MAIN_THREAD_WITH_hWnd; 1558 1559 ARG(jResizable) = jResizable; 1560 return PERFORM_AND_RETURN(); 1561 } 1562 1563 /* 1564 * Class: com_sun_glass_ui_win_WinWindow 1565 * Method: _setVisible 1566 * Signature: (JZ)Z 1567 */ 1568 JNIEXPORT jboolean JNICALL Java_com_sun_glass_ui_win_WinWindow__1setVisible 1569 (JNIEnv *env, jobject jThis, jlong ptr, jboolean visible) 1570 { 1571 ENTER_MAIN_THREAD() 1572 { 1573 GlassWindow *pWindow = GlassWindow::FromHandle(hWnd); 1574 if (!visible) { 1575 if (pWindow) { 1576 pWindow->UngrabFocus(); 1577 } 1578 1579 if (activeTouchWindow == hWnd) { 1580 pWindow->HandleViewTouchEvent(hWnd, 0, 0, 0); 1581 activeTouchWindow = 0; 1582 } 1583 } 1584 1585 1586 ::ShowWindow(hWnd, visible ? SW_SHOW : SW_HIDE); 1587 1588 if (visible) { 1589 if (pWindow) { 1590 if (pWindow->IsFocusable()) { 1591 ::SetForegroundWindow(hWnd); 1592 } else { 1593 // RT-14197: 1594 // On some latest platform versions, unfocusable windows 1595 // are shown below the currently active window, so we 1596 // need to pull them to front explicitly. However, 1597 // neither BringWindowToTop nor SetForegroundWindow() 1598 // can be used because of the window unfocusability, so 1599 // here is a workaround: we first made the window TOPMOST 1600 // and then reset this flag to just TOP. 1601 ::SetWindowPos(hWnd, HWND_TOPMOST, 0, 0, 0, 0, 1602 SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE); 1603 ::SetWindowPos(hWnd, HWND_TOP, 0, 0, 0, 0, 1604 SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE); 1605 } 1606 } 1607 ::UpdateWindow(hWnd); 1608 } 1609 } 1610 jboolean visible; 1611 LEAVE_MAIN_THREAD_WITH_hWnd; 1612 1613 ARG(visible) = visible; 1614 PERFORM(); 1615 return visible; 1616 } 1617 1618 /* 1619 * Class: com_sun_glass_ui_win_WinWindow 1620 * Method: _requestFocus 1621 * Signature: (JI)Z 1622 */ 1623 JNIEXPORT jboolean JNICALL Java_com_sun_glass_ui_win_WinWindow__1requestFocus 1624 (JNIEnv *env, jobject jThis, jlong ptr, jint event) 1625 { 1626 ENTER_MAIN_THREAD_AND_RETURN(jboolean) 1627 { 1628 GlassWindow *pWindow = GlassWindow::FromHandle(hWnd); 1629 return bool_to_jbool(pWindow && pWindow->RequestFocus(event)); 1630 } 1631 jint event; 1632 LEAVE_MAIN_THREAD_WITH_hWnd; 1633 1634 ARG(event) = event; 1635 1636 return PERFORM_AND_RETURN(); 1637 } 1638 1639 /* 1640 * Class: com_sun_glass_ui_win_WinWindow 1641 * Method: _grabFocus 1642 * Signature: (J)Z 1643 */ 1644 JNIEXPORT jboolean JNICALL Java_com_sun_glass_ui_win_WinWindow__1grabFocus 1645 (JNIEnv *env, jobject jThis, jlong ptr) 1646 { 1647 ENTER_MAIN_THREAD_AND_RETURN(jboolean) 1648 { 1649 GlassWindow *pWindow = GlassWindow::FromHandle(hWnd); 1650 return bool_to_jbool(pWindow && pWindow->GrabFocus()); 1651 } 1652 LEAVE_MAIN_THREAD_WITH_hWnd; 1653 1654 return PERFORM_AND_RETURN(); 1655 } 1656 1657 /* 1658 * Class: com_sun_glass_ui_win_WinWindow 1659 * Method: _ungrabFocus 1660 * Signature: (J)V 1661 */ 1662 JNIEXPORT void JNICALL Java_com_sun_glass_ui_win_WinWindow__1ungrabFocus 1663 (JNIEnv *env, jobject jThis, jlong ptr) 1664 { 1665 ENTER_MAIN_THREAD() 1666 { 1667 GlassWindow *pWindow = GlassWindow::FromHandle(hWnd); 1668 if (pWindow) { 1669 pWindow->UngrabFocus(); 1670 } 1671 } 1672 LEAVE_MAIN_THREAD_WITH_hWnd; 1673 1674 PERFORM(); 1675 } 1676 1677 /* 1678 * Class: com_sun_glass_ui_win_WinWindow 1679 * Method: _minimize 1680 * Signature: (JZ)Z 1681 */ 1682 JNIEXPORT jboolean JNICALL Java_com_sun_glass_ui_win_WinWindow__1minimize 1683 (JNIEnv *env, jobject jThis, jlong ptr, jboolean minimize) 1684 { 1685 ENTER_MAIN_THREAD() 1686 { 1687 ::ShowWindow(hWnd, minimize ? SW_MINIMIZE : SW_RESTORE); 1688 } 1689 jboolean minimize; 1690 LEAVE_MAIN_THREAD_WITH_hWnd; 1691 1692 ARG(minimize) = minimize; 1693 PERFORM(); 1694 1695 return JNI_TRUE; 1696 } 1697 1698 /* 1699 * Class: com_sun_glass_ui_win_WinWindow 1700 * Method: _maximize 1701 * Signature: (JZ)Z 1702 */ 1703 JNIEXPORT jboolean JNICALL Java_com_sun_glass_ui_win_WinWindow__1maximize 1704 (JNIEnv *env, jobject jThis, jlong ptr, jboolean maximize, jboolean wasMaximized) 1705 { 1706 ENTER_MAIN_THREAD() 1707 { 1708 ::ShowWindow(hWnd, maximize ? SW_MAXIMIZE : SW_RESTORE); 1709 } 1710 jboolean maximize; 1711 LEAVE_MAIN_THREAD_WITH_hWnd; 1712 1713 ARG(maximize) = maximize; 1714 PERFORM(); 1715 1716 return JNI_TRUE; 1717 } 1718 1719 /* 1720 * Class: com_sun_glass_ui_win_WinWindow 1721 * Method: _setMinimumSize 1722 * Signature: (JII)Z 1723 */ 1724 JNIEXPORT jboolean JNICALL Java_com_sun_glass_ui_win_WinWindow__1setMinimumSize 1725 (JNIEnv *env, jobject jThis, jlong ptr, jint minWidth, jint minHeight) 1726 { 1727 ENTER_MAIN_THREAD_AND_RETURN(jboolean) 1728 { 1729 GlassWindow *pWindow = GlassWindow::FromHandle(hWnd); 1730 if (pWindow) { 1731 pWindow->setMinSize(minWidth, minHeight); 1732 return JNI_TRUE; 1733 } 1734 return JNI_FALSE; 1735 } 1736 jint minWidth; 1737 jint minHeight; 1738 LEAVE_MAIN_THREAD_WITH_hWnd; 1739 1740 ARG(minWidth) = minWidth == 0 ? -1 : minWidth; 1741 ARG(minHeight) = minHeight == 0 ? -1 : minHeight; 1742 return PERFORM_AND_RETURN(); 1743 } 1744 1745 /* 1746 * Class: com_sun_glass_ui_win_WinWindow 1747 * Method: _setMaximumSize 1748 * Signature: (JII)Z 1749 */ 1750 JNIEXPORT jboolean JNICALL Java_com_sun_glass_ui_win_WinWindow__1setMaximumSize 1751 (JNIEnv *env, jobject jThis, jlong ptr, jint maxWidth, jint maxHeight) 1752 { 1753 ENTER_MAIN_THREAD_AND_RETURN(jboolean) 1754 { 1755 GlassWindow *pWindow = GlassWindow::FromHandle(hWnd); 1756 if (pWindow) { 1757 pWindow->setMaxSize(maxWidth, maxHeight); 1758 return JNI_TRUE; 1759 } 1760 return JNI_FALSE; 1761 } 1762 jint maxWidth; 1763 jint maxHeight; 1764 LEAVE_MAIN_THREAD_WITH_hWnd; 1765 1766 ARG(maxWidth) = maxWidth; 1767 ARG(maxHeight) = maxHeight; 1768 return PERFORM_AND_RETURN(); 1769 } 1770 1771 /* 1772 * Class: com_sun_glass_ui_win_WinWindow 1773 * Method: _setIcon 1774 * Signature: (JLcom/sun/glass/ui/Pixels;)V 1775 */ 1776 JNIEXPORT void JNICALL Java_com_sun_glass_ui_win_WinWindow__1setIcon 1777 (JNIEnv *env, jobject jThis, jlong ptr, jobject jPixels) 1778 { 1779 HWND hWnd = (HWND)ptr; 1780 GlassWindow *pWindow = GlassWindow::FromHandle(hWnd); 1781 if (pWindow) { 1782 pWindow->SetIcon(!jPixels ? NULL : Pixels::CreateIcon(env, jPixels)); 1783 } 1784 } 1785 1786 /* 1787 * Class: com_sun_glass_ui_win_WinWindow 1788 * Method: _toFront 1789 * Signature: (J)V 1790 */ 1791 JNIEXPORT void JNICALL Java_com_sun_glass_ui_win_WinWindow__1toFront 1792 (JNIEnv *env, jobject jThis, jlong ptr) 1793 { 1794 ENTER_MAIN_THREAD() 1795 { 1796 GlassWindow *pWindow = GlassWindow::FromHandle(hWnd); 1797 // See comment in __1setVisible() above about unfocusable windows 1798 if (pWindow && !pWindow->IsFocusable()) { 1799 ::SetWindowPos(hWnd, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE); 1800 } 1801 ::SetWindowPos(hWnd, HWND_TOP, 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: _toBack 1811 * Signature: (J)V 1812 */ 1813 JNIEXPORT void JNICALL Java_com_sun_glass_ui_win_WinWindow__1toBack 1814 (JNIEnv *env, jobject jThis, jlong ptr) 1815 { 1816 ENTER_MAIN_THREAD() 1817 { 1818 ::SetWindowPos(hWnd, HWND_BOTTOM, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE); 1819 } 1820 LEAVE_MAIN_THREAD_WITH_hWnd; 1821 1822 PERFORM(); 1823 } 1824 1825 /* 1826 * Class: com_sun_glass_ui_win_WinWindow 1827 * Method: _getEmbeddedX 1828 * Signature: (J)I 1829 */ 1830 JNIEXPORT jint JNICALL Java_com_sun_glass_ui_win_WinWindow__1getEmbeddedX 1831 (JNIEnv *env, jobject jThis, jlong ptr) 1832 { 1833 ENTER_MAIN_THREAD_AND_RETURN(jint) 1834 { 1835 GlassWindow *pWindow = GlassWindow::FromHandle(hWnd); 1836 HWND delegateHWnd = pWindow ? pWindow->GetDelegateWindow() : 0; 1837 RECT rect = {0}; 1838 ::MapWindowPoints(delegateHWnd ? delegateHWnd : hWnd, (HWND)NULL, (LPPOINT)&rect, (sizeof(RECT)/sizeof(POINT))); 1839 return rect.left; 1840 } 1841 LEAVE_MAIN_THREAD_WITH_hWnd; 1842 1843 return PERFORM_AND_RETURN(); 1844 } 1845 1846 /* 1847 * Class: com_sun_glass_ui_win_WinWindow 1848 * Method: _getEmbeddedY 1849 * Signature: (J)I 1850 */ 1851 JNIEXPORT jint JNICALL Java_com_sun_glass_ui_win_WinWindow__1getEmbeddedY 1852 (JNIEnv *env, jobject jThis, jlong ptr) 1853 { 1854 ENTER_MAIN_THREAD_AND_RETURN(jint) 1855 { 1856 GlassWindow *pWindow = GlassWindow::FromHandle(hWnd); 1857 HWND delegateHWnd = pWindow ? pWindow->GetDelegateWindow() : 0; 1858 RECT rect = {0}; 1859 ::MapWindowPoints(delegateHWnd ? delegateHWnd : hWnd, (HWND)NULL, (LPPOINT)&rect, (sizeof(RECT)/sizeof(POINT))); 1860 return rect.top; 1861 } 1862 LEAVE_MAIN_THREAD_WITH_hWnd; 1863 1864 return PERFORM_AND_RETURN(); 1865 } 1866 1867 /* 1868 * Class: com_sun_glass_ui_win_WinWindow 1869 * Method: _setCursor 1870 * Signature: (Lcom/sun/glass/ui/Cursor;)V 1871 */ 1872 JNIEXPORT void JNICALL Java_com_sun_glass_ui_win_WinWindow__1setCursor 1873 (JNIEnv *env, jobject jThis, jlong ptr, jobject jCursor) 1874 { 1875 ENTER_MAIN_THREAD() 1876 { 1877 const HCURSOR cursor = JCursorToHCURSOR(GetEnv(), jCursor); 1878 1879 GlassWindow *pWindow = GlassWindow::FromHandle(hWnd); 1880 if (pWindow) { 1881 pWindow->SetCursor(cursor); 1882 1883 // Update the delegate window as well if present 1884 HWND delegateHwnd = pWindow->GetDelegateWindow(); 1885 if (delegateHwnd) { 1886 BaseWnd *pDelegateWindow = BaseWnd::FromHandle(delegateHwnd); 1887 if (pDelegateWindow) { 1888 pDelegateWindow->SetCursor(cursor); 1889 } 1890 } 1891 } 1892 } 1893 DECL_jobject(jCursor); 1894 LEAVE_MAIN_THREAD_WITH_hWnd; 1895 1896 ARG(jCursor) = jCursor; 1897 PERFORM(); 1898 } 1899 1900 } // extern "C"