1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/widget/windows/nsToolkit.cpp Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,235 @@ 1.4 +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 1.5 +/* This Source Code Form is subject to the terms of the Mozilla Public 1.6 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.7 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.8 + 1.9 +#include "nsToolkit.h" 1.10 +#include "nsAppShell.h" 1.11 +#include "nsWindow.h" 1.12 +#include "nsWidgetsCID.h" 1.13 +#include "prmon.h" 1.14 +#include "prtime.h" 1.15 +#include "nsIServiceManager.h" 1.16 +#include "nsComponentManagerUtils.h" 1.17 +#include <objbase.h> 1.18 +#include "WinUtils.h" 1.19 + 1.20 +#include "nsUXThemeData.h" 1.21 + 1.22 +// unknwn.h is needed to build with WIN32_LEAN_AND_MEAN 1.23 +#include <unknwn.h> 1.24 + 1.25 +using namespace mozilla::widget; 1.26 + 1.27 +nsToolkit* nsToolkit::gToolkit = nullptr; 1.28 +HINSTANCE nsToolkit::mDllInstance = 0; 1.29 +static const unsigned long kD3DUsageDelay = 5000; 1.30 + 1.31 +static void 1.32 +StartAllowingD3D9(nsITimer *aTimer, void *aClosure) 1.33 +{ 1.34 + if (XRE_GetWindowsEnvironment() == WindowsEnvironmentType_Desktop) { 1.35 + nsWindow::StartAllowingD3D9(true); 1.36 + } 1.37 +} 1.38 + 1.39 +MouseTrailer* nsToolkit::gMouseTrailer; 1.40 + 1.41 +//------------------------------------------------------------------------- 1.42 +// 1.43 +// constructor 1.44 +// 1.45 +//------------------------------------------------------------------------- 1.46 +nsToolkit::nsToolkit() 1.47 +{ 1.48 + MOZ_COUNT_CTOR(nsToolkit); 1.49 + 1.50 +#if defined(MOZ_STATIC_COMPONENT_LIBS) 1.51 + nsToolkit::Startup(GetModuleHandle(nullptr)); 1.52 +#endif 1.53 + 1.54 + gMouseTrailer = &mMouseTrailer; 1.55 + 1.56 + if (XRE_GetWindowsEnvironment() == WindowsEnvironmentType_Desktop) { 1.57 + mD3D9Timer = do_CreateInstance("@mozilla.org/timer;1"); 1.58 + mD3D9Timer->InitWithFuncCallback(::StartAllowingD3D9, 1.59 + nullptr, 1.60 + kD3DUsageDelay, 1.61 + nsITimer::TYPE_ONE_SHOT); 1.62 + } 1.63 +} 1.64 + 1.65 + 1.66 +//------------------------------------------------------------------------- 1.67 +// 1.68 +// destructor 1.69 +// 1.70 +//------------------------------------------------------------------------- 1.71 +nsToolkit::~nsToolkit() 1.72 +{ 1.73 + MOZ_COUNT_DTOR(nsToolkit); 1.74 + gMouseTrailer = nullptr; 1.75 +} 1.76 + 1.77 +void 1.78 +nsToolkit::Startup(HMODULE hModule) 1.79 +{ 1.80 + nsToolkit::mDllInstance = hModule; 1.81 + WinUtils::Initialize(); 1.82 + nsUXThemeData::Initialize(); 1.83 +} 1.84 + 1.85 +void 1.86 +nsToolkit::Shutdown() 1.87 +{ 1.88 + delete gToolkit; 1.89 + gToolkit = nullptr; 1.90 +} 1.91 + 1.92 +void 1.93 +nsToolkit::StartAllowingD3D9() 1.94 +{ 1.95 + if (XRE_GetWindowsEnvironment() == WindowsEnvironmentType_Desktop) { 1.96 + nsToolkit::GetToolkit()->mD3D9Timer->Cancel(); 1.97 + nsWindow::StartAllowingD3D9(false); 1.98 + } 1.99 +} 1.100 + 1.101 +//------------------------------------------------------------------------- 1.102 +// 1.103 +// Return the nsToolkit for the current thread. If a toolkit does not 1.104 +// yet exist, then one will be created... 1.105 +// 1.106 +//------------------------------------------------------------------------- 1.107 +// static 1.108 +nsToolkit* nsToolkit::GetToolkit() 1.109 +{ 1.110 + if (!gToolkit) { 1.111 + gToolkit = new nsToolkit(); 1.112 + } 1.113 + 1.114 + return gToolkit; 1.115 +} 1.116 + 1.117 + 1.118 +//------------------------------------------------------------------------- 1.119 +// 1.120 +// 1.121 +//------------------------------------------------------------------------- 1.122 +MouseTrailer::MouseTrailer() : mMouseTrailerWindow(nullptr), mCaptureWindow(nullptr), 1.123 + mIsInCaptureMode(false), mEnabled(true) 1.124 +{ 1.125 +} 1.126 +//------------------------------------------------------------------------- 1.127 +// 1.128 +// 1.129 +//------------------------------------------------------------------------- 1.130 +MouseTrailer::~MouseTrailer() 1.131 +{ 1.132 + DestroyTimer(); 1.133 +} 1.134 +//------------------------------------------------------------------------- 1.135 +// 1.136 +// 1.137 +//------------------------------------------------------------------------- 1.138 +void MouseTrailer::SetMouseTrailerWindow(HWND aWnd) 1.139 +{ 1.140 + if (mMouseTrailerWindow != aWnd && mTimer) { 1.141 + // Make sure TimerProc is fired at least once for the old window 1.142 + TimerProc(nullptr, nullptr); 1.143 + } 1.144 + mMouseTrailerWindow = aWnd; 1.145 + CreateTimer(); 1.146 +} 1.147 + 1.148 +//------------------------------------------------------------------------- 1.149 +// 1.150 +// 1.151 +//------------------------------------------------------------------------- 1.152 +void MouseTrailer::SetCaptureWindow(HWND aWnd) 1.153 +{ 1.154 + mCaptureWindow = aWnd; 1.155 + if (mCaptureWindow) { 1.156 + mIsInCaptureMode = true; 1.157 + } 1.158 +} 1.159 + 1.160 +//------------------------------------------------------------------------- 1.161 +// 1.162 +// 1.163 +//------------------------------------------------------------------------- 1.164 +nsresult MouseTrailer::CreateTimer() 1.165 +{ 1.166 + if (mTimer || !mEnabled) { 1.167 + return NS_OK; 1.168 + } 1.169 + 1.170 + nsresult rv; 1.171 + mTimer = do_CreateInstance("@mozilla.org/timer;1", &rv); 1.172 + NS_ENSURE_SUCCESS(rv, rv); 1.173 + 1.174 + return mTimer->InitWithFuncCallback(TimerProc, nullptr, 200, 1.175 + nsITimer::TYPE_REPEATING_SLACK); 1.176 +} 1.177 + 1.178 +//------------------------------------------------------------------------- 1.179 +// 1.180 +// 1.181 +//------------------------------------------------------------------------- 1.182 +void MouseTrailer::DestroyTimer() 1.183 +{ 1.184 + if (mTimer) { 1.185 + mTimer->Cancel(); 1.186 + mTimer = nullptr; 1.187 + } 1.188 +} 1.189 + 1.190 +//------------------------------------------------------------------------- 1.191 +// 1.192 +// 1.193 +//------------------------------------------------------------------------- 1.194 +void MouseTrailer::TimerProc(nsITimer* aTimer, void* aClosure) 1.195 +{ 1.196 + MouseTrailer *mtrailer = nsToolkit::gMouseTrailer; 1.197 + NS_ASSERTION(mtrailer, "MouseTrailer still firing after deletion!"); 1.198 + 1.199 + // Check to see if we are in mouse capture mode, 1.200 + // Once capture ends we could still get back one more timer event. 1.201 + // Capture could end outside our window. 1.202 + // Also, for some reason when the mouse is on the frame it thinks that 1.203 + // it is inside the window that is being captured. 1.204 + if (mtrailer->mCaptureWindow) { 1.205 + if (mtrailer->mCaptureWindow != mtrailer->mMouseTrailerWindow) { 1.206 + return; 1.207 + } 1.208 + } else { 1.209 + if (mtrailer->mIsInCaptureMode) { 1.210 + // mMouseTrailerWindow could be bad from rolling over the frame, so clear 1.211 + // it if we were capturing and now this is the first timer callback 1.212 + // since we canceled the capture 1.213 + mtrailer->mMouseTrailerWindow = nullptr; 1.214 + mtrailer->mIsInCaptureMode = false; 1.215 + return; 1.216 + } 1.217 + } 1.218 + 1.219 + if (mtrailer->mMouseTrailerWindow && ::IsWindow(mtrailer->mMouseTrailerWindow)) { 1.220 + POINT mp; 1.221 + DWORD pos = ::GetMessagePos(); 1.222 + mp.x = GET_X_LPARAM(pos); 1.223 + mp.y = GET_Y_LPARAM(pos); 1.224 + HWND mouseWnd = ::WindowFromPoint(mp); 1.225 + if (mtrailer->mMouseTrailerWindow != mouseWnd) { 1.226 + // Notify someone that a mouse exit happened. 1.227 + PostMessage(mtrailer->mMouseTrailerWindow, WM_MOUSELEAVE, 0, 0); 1.228 + 1.229 + // we are out of this window, destroy timer 1.230 + mtrailer->DestroyTimer(); 1.231 + mtrailer->mMouseTrailerWindow = nullptr; 1.232 + } 1.233 + } else { 1.234 + mtrailer->DestroyTimer(); 1.235 + mtrailer->mMouseTrailerWindow = nullptr; 1.236 + } 1.237 +} 1.238 +