/extlibs/SFML/src/SFML/Window/Window.cpp
C++ | 452 lines | 269 code | 92 blank | 91 comment | 35 complexity | 955373c734b7ce26f0e8a059c3e93b93 MD5 | raw file
1//////////////////////////////////////////////////////////// 2// 3// SFML - Simple and Fast Multimedia Library 4// Copyright (C) 2007-2009 Laurent Gomila (laurent.gom@gmail.com) 5// 6// This software is provided 'as-is', without any express or implied warranty. 7// In no event will the authors be held liable for any damages arising from the use of this software. 8// 9// Permission is granted to anyone to use this software for any purpose, 10// including commercial applications, and to alter it and redistribute it freely, 11// subject to the following restrictions: 12// 13// 1. The origin of this software must not be misrepresented; 14// you must not claim that you wrote the original software. 15// If you use this software in a product, an acknowledgment 16// in the product documentation would be appreciated but is not required. 17// 18// 2. Altered source versions must be plainly marked as such, 19// and must not be misrepresented as being the original software. 20// 21// 3. This notice may not be removed or altered from any source distribution. 22// 23//////////////////////////////////////////////////////////// 24 25//////////////////////////////////////////////////////////// 26// Headers 27//////////////////////////////////////////////////////////// 28#include <SFML/Window/Window.hpp> 29#include <SFML/Window/GlContext.hpp> 30#include <SFML/Window/WindowImpl.hpp> 31#include <SFML/System/Sleep.hpp> 32#include <SFML/System/Err.hpp> 33 34 35//////////////////////////////////////////////////////////// 36// Private data 37//////////////////////////////////////////////////////////// 38namespace 39{ 40 const sf::Window* fullscreenWindow = NULL; 41} 42 43 44namespace sf 45{ 46//////////////////////////////////////////////////////////// 47Window::Window() : 48myWindow (NULL), 49myContext (NULL), 50myLastFrameTime (0.f), 51myIsExternal (false), 52myFramerateLimit(0), 53mySetCursorPosX (0xFFFF), 54mySetCursorPosY (0xFFFF) 55{ 56 57} 58 59 60//////////////////////////////////////////////////////////// 61Window::Window(VideoMode mode, const std::string& title, unsigned long style, const ContextSettings& settings) : 62myWindow (NULL), 63myContext (NULL), 64myLastFrameTime (0.f), 65myIsExternal (false), 66myFramerateLimit(0), 67mySetCursorPosX (0xFFFF), 68mySetCursorPosY (0xFFFF) 69{ 70 Create(mode, title, style, settings); 71} 72 73 74//////////////////////////////////////////////////////////// 75Window::Window(WindowHandle handle, const ContextSettings& settings) : 76myWindow (NULL), 77myContext (NULL), 78myLastFrameTime (0.f), 79myIsExternal (true), 80myFramerateLimit(0), 81mySetCursorPosX (0xFFFF), 82mySetCursorPosY (0xFFFF) 83{ 84 Create(handle, settings); 85} 86 87 88//////////////////////////////////////////////////////////// 89Window::~Window() 90{ 91 Close(); 92} 93 94 95//////////////////////////////////////////////////////////// 96void Window::Create(VideoMode mode, const std::string& title, unsigned long style, const ContextSettings& settings) 97{ 98 // Destroy the previous window implementation 99 Close(); 100 101 // Fullscreen style requires some tests 102 if (style & Style::Fullscreen) 103 { 104 // Make sure there's not already a fullscreen window (only one is allowed) 105 if (fullscreenWindow) 106 { 107 Err() << "Creating two fullscreen windows is not allowed, switching to windowed mode" << std::endl; 108 style &= ~Style::Fullscreen; 109 } 110 else 111 { 112 // Make sure that the chosen video mode is compatible 113 if (!mode.IsValid()) 114 { 115 Err() << "The requested video mode is not available, switching to a valid mode" << std::endl; 116 mode = VideoMode::GetFullscreenModes()[0]; 117 } 118 119 // Update the fullscreen window 120 fullscreenWindow = this; 121 } 122 } 123 124 // Check validity of style 125 if ((style & Style::Close) || (style & Style::Resize)) 126 style |= Style::Titlebar; 127 128 // Recreate the window implementation 129 myWindow = priv::WindowImpl::New(mode, title, style); 130 131 // Recreate the context 132 myContext = priv::GlContext::New(myWindow, mode.BitsPerPixel, settings); 133 134 // Perform common initializations 135 Initialize(); 136} 137 138 139//////////////////////////////////////////////////////////// 140void Window::Create(WindowHandle handle, const ContextSettings& settings) 141{ 142 // Destroy the previous window implementation 143 Close(); 144 145 // Recreate the window implementation 146 myWindow = priv::WindowImpl::New(handle); 147 148 // Recreate the context 149 myContext = priv::GlContext::New(myWindow, VideoMode::GetDesktopMode().BitsPerPixel, settings); 150 151 // Perform common initializations 152 Initialize(); 153} 154 155 156//////////////////////////////////////////////////////////// 157void Window::Close() 158{ 159 if (myContext) 160 { 161 // Delete the context 162 delete myContext; 163 myContext = NULL; 164 } 165 166 if (myWindow) 167 { 168 // Delete the window implementation 169 delete myWindow; 170 myWindow = NULL; 171 } 172 173 // Update the fullscreen window 174 if (this == fullscreenWindow) 175 fullscreenWindow = NULL; 176} 177 178 179//////////////////////////////////////////////////////////// 180bool Window::IsOpened() const 181{ 182 return myWindow != NULL; 183} 184 185 186//////////////////////////////////////////////////////////// 187unsigned int Window::GetWidth() const 188{ 189 return myWindow ? myWindow->GetWidth() : 0; 190} 191 192 193//////////////////////////////////////////////////////////// 194unsigned int Window::GetHeight() const 195{ 196 return myWindow ? myWindow->GetHeight() : 0; 197} 198 199 200//////////////////////////////////////////////////////////// 201const ContextSettings& Window::GetSettings() const 202{ 203 static const ContextSettings empty(0, 0, 0); 204 205 return myContext ? myContext->GetSettings() : empty; 206} 207 208 209//////////////////////////////////////////////////////////// 210bool Window::GetEvent(Event& event) 211{ 212 if (myWindow && myWindow->PopEvent(event, false)) 213 { 214 return FilterEvent(event); 215 } 216 else 217 { 218 return false; 219 } 220} 221 222 223//////////////////////////////////////////////////////////// 224bool Window::WaitEvent(Event& event) 225{ 226 if (myWindow && myWindow->PopEvent(event, true)) 227 { 228 return FilterEvent(event); 229 } 230 else 231 { 232 return false; 233 } 234} 235 236 237//////////////////////////////////////////////////////////// 238void Window::UseVerticalSync(bool enabled) 239{ 240 if (SetActive()) 241 myContext->UseVerticalSync(enabled); 242} 243 244 245//////////////////////////////////////////////////////////// 246void Window::ShowMouseCursor(bool show) 247{ 248 if (myWindow) 249 myWindow->ShowMouseCursor(show); 250} 251 252 253//////////////////////////////////////////////////////////// 254void Window::SetCursorPosition(unsigned int x, unsigned int y) 255{ 256 if (myWindow) 257 { 258 // Keep coordinates for later checking (to reject the generated MouseMoved event) 259 mySetCursorPosX = x; 260 mySetCursorPosY = y; 261 262 myWindow->SetCursorPosition(x, y); 263 } 264} 265 266 267//////////////////////////////////////////////////////////// 268void Window::SetPosition(int x, int y) 269{ 270 if (myWindow) 271 myWindow->SetPosition(x, y); 272} 273 274 275//////////////////////////////////////////////////////////// 276void Window::SetSize(unsigned int width, unsigned int height) 277{ 278 if (myWindow) 279 myWindow->SetSize(width, height); 280} 281 282 283//////////////////////////////////////////////////////////// 284void Window::SetTitle(const std::string& title) 285{ 286 if (myWindow) 287 myWindow->SetTitle(title); 288} 289 290 291//////////////////////////////////////////////////////////// 292void Window::Show(bool show) 293{ 294 if (myWindow) 295 myWindow->Show(show); 296} 297 298 299//////////////////////////////////////////////////////////// 300void Window::EnableKeyRepeat(bool enabled) 301{ 302 if (myWindow) 303 myWindow->EnableKeyRepeat(enabled); 304} 305 306 307//////////////////////////////////////////////////////////// 308void Window::SetIcon(unsigned int width, unsigned int height, const Uint8* pixels) 309{ 310 if (myWindow) 311 myWindow->SetIcon(width, height, pixels); 312} 313 314 315//////////////////////////////////////////////////////////// 316bool Window::SetActive(bool active) const 317{ 318 if (myContext) 319 { 320 if (myContext->SetActive(active)) 321 { 322 return true; 323 } 324 else 325 { 326 Err() << "Failed to activate the window's context" << std::endl; 327 return false; 328 } 329 } 330 else 331 { 332 return false; 333 } 334} 335 336 337//////////////////////////////////////////////////////////// 338void Window::Display() 339{ 340 // Limit the framerate if needed 341 if (myFramerateLimit > 0) 342 { 343 float remainingTime = 1.f / myFramerateLimit - myClock.GetElapsedTime(); 344 if (remainingTime > 0) 345 Sleep(remainingTime); 346 } 347 348 // Measure the time elapsed since last frame 349 myLastFrameTime = myClock.GetElapsedTime(); 350 myClock.Reset(); 351 352 // Display the backbuffer on screen 353 if (SetActive()) 354 myContext->Display(); 355} 356 357 358//////////////////////////////////////////////////////////// 359const Input& Window::GetInput() const 360{ 361 return myInput; 362} 363 364 365//////////////////////////////////////////////////////////// 366void Window::SetFramerateLimit(unsigned int limit) 367{ 368 myFramerateLimit = limit; 369} 370 371 372//////////////////////////////////////////////////////////// 373float Window::GetFrameTime() const 374{ 375 return myLastFrameTime; 376} 377 378 379//////////////////////////////////////////////////////////// 380void Window::SetJoystickThreshold(float threshold) 381{ 382 if (myWindow) 383 myWindow->SetJoystickThreshold(threshold); 384} 385 386 387//////////////////////////////////////////////////////////// 388WindowHandle Window::GetSystemHandle() const 389{ 390 return myWindow ? myWindow->GetSystemHandle() : 0; 391} 392 393 394//////////////////////////////////////////////////////////// 395void Window::OnCreate() 396{ 397 // Nothing by default 398} 399 400 401//////////////////////////////////////////////////////////// 402void Window::OnResize() 403{ 404 // Nothing by default 405} 406 407 408//////////////////////////////////////////////////////////// 409bool Window::FilterEvent(const Event& event) 410{ 411 // Notify the input object 412 myInput.OnEvent(event); 413 414 // Notify resize events to the derived class 415 if (event.Type == Event::Resized) 416 OnResize(); 417 418 // Don't forward to the user MouseMove events generated by SetCursorPosition 419 if ((event.Type == Event::MouseMoved) && 420 (event.MouseMove.X == mySetCursorPosX) && 421 (event.MouseMove.Y == mySetCursorPosY)) 422 { 423 mySetCursorPosX = 0xFFFF; 424 mySetCursorPosY = 0xFFFF; 425 return false; 426 } 427 428 return true; 429} 430 431 432//////////////////////////////////////////////////////////// 433void Window::Initialize() 434{ 435 // Setup default behaviours (to get a consistent behaviour across different implementations) 436 Show(true); 437 UseVerticalSync(false); 438 ShowMouseCursor(true); 439 EnableKeyRepeat(true); 440 441 // Reset frame time 442 myClock.Reset(); 443 myLastFrameTime = 0.f; 444 445 // Activate the window 446 SetActive(); 447 448 // Notify the derived class 449 OnCreate(); 450} 451 452} // namespace sf