/extlibs/SFML/src/SFML/Window/Window.cpp

https://bitbucket.org/hugoruscitti/pilascpp · 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. // Headers
  26. ////////////////////////////////////////////////////////////
  27. #include <SFML/Window/Window.hpp>
  28. #include <SFML/Window/GlContext.hpp>
  29. #include <SFML/Window/WindowImpl.hpp>
  30. #include <SFML/System/Sleep.hpp>
  31. #include <SFML/System/Err.hpp>
  32. ////////////////////////////////////////////////////////////
  33. // Private data
  34. ////////////////////////////////////////////////////////////
  35. namespace
  36. {
  37. const sf::Window* fullscreenWindow = NULL;
  38. }
  39. namespace sf
  40. {
  41. ////////////////////////////////////////////////////////////
  42. Window::Window() :
  43. myWindow (NULL),
  44. myContext (NULL),
  45. myLastFrameTime (0.f),
  46. myIsExternal (false),
  47. myFramerateLimit(0),
  48. mySetCursorPosX (0xFFFF),
  49. mySetCursorPosY (0xFFFF)
  50. {
  51. }
  52. ////////////////////////////////////////////////////////////
  53. Window::Window(VideoMode mode, const std::string& title, unsigned long style, const ContextSettings& settings) :
  54. myWindow (NULL),
  55. myContext (NULL),
  56. myLastFrameTime (0.f),
  57. myIsExternal (false),
  58. myFramerateLimit(0),
  59. mySetCursorPosX (0xFFFF),
  60. mySetCursorPosY (0xFFFF)
  61. {
  62. Create(mode, title, style, settings);
  63. }
  64. ////////////////////////////////////////////////////////////
  65. Window::Window(WindowHandle handle, const ContextSettings& settings) :
  66. myWindow (NULL),
  67. myContext (NULL),
  68. myLastFrameTime (0.f),
  69. myIsExternal (true),
  70. myFramerateLimit(0),
  71. mySetCursorPosX (0xFFFF),
  72. mySetCursorPosY (0xFFFF)
  73. {
  74. Create(handle, settings);
  75. }
  76. ////////////////////////////////////////////////////////////
  77. Window::~Window()
  78. {
  79. Close();
  80. }
  81. ////////////////////////////////////////////////////////////
  82. void Window::Create(VideoMode mode, const std::string& title, unsigned long style, const ContextSettings& settings)
  83. {
  84. // Destroy the previous window implementation
  85. Close();
  86. // Fullscreen style requires some tests
  87. if (style & Style::Fullscreen)
  88. {
  89. // Make sure there's not already a fullscreen window (only one is allowed)
  90. if (fullscreenWindow)
  91. {
  92. Err() << "Creating two fullscreen windows is not allowed, switching to windowed mode" << std::endl;
  93. style &= ~Style::Fullscreen;
  94. }
  95. else
  96. {
  97. // Make sure that the chosen video mode is compatible
  98. if (!mode.IsValid())
  99. {
  100. Err() << "The requested video mode is not available, switching to a valid mode" << std::endl;
  101. mode = VideoMode::GetFullscreenModes()[0];
  102. }
  103. // Update the fullscreen window
  104. fullscreenWindow = this;
  105. }
  106. }
  107. // Check validity of style
  108. if ((style & Style::Close) || (style & Style::Resize))
  109. style |= Style::Titlebar;
  110. // Recreate the window implementation
  111. myWindow = priv::WindowImpl::New(mode, title, style);
  112. // Recreate the context
  113. myContext = priv::GlContext::New(myWindow, mode.BitsPerPixel, settings);
  114. // Perform common initializations
  115. Initialize();
  116. }
  117. ////////////////////////////////////////////////////////////
  118. void Window::Create(WindowHandle handle, const ContextSettings& settings)
  119. {
  120. // Destroy the previous window implementation
  121. Close();
  122. // Recreate the window implementation
  123. myWindow = priv::WindowImpl::New(handle);
  124. // Recreate the context
  125. myContext = priv::GlContext::New(myWindow, VideoMode::GetDesktopMode().BitsPerPixel, settings);
  126. // Perform common initializations
  127. Initialize();
  128. }
  129. ////////////////////////////////////////////////////////////
  130. void Window::Close()
  131. {
  132. if (myContext)
  133. {
  134. // Delete the context
  135. delete myContext;
  136. myContext = NULL;
  137. }
  138. if (myWindow)
  139. {
  140. // Delete the window implementation
  141. delete myWindow;
  142. myWindow = NULL;
  143. }
  144. // Update the fullscreen window
  145. if (this == fullscreenWindow)
  146. fullscreenWindow = NULL;
  147. }
  148. ////////////////////////////////////////////////////////////
  149. bool Window::IsOpened() const
  150. {
  151. return myWindow != NULL;
  152. }
  153. ////////////////////////////////////////////////////////////
  154. unsigned int Window::GetWidth() const
  155. {
  156. return myWindow ? myWindow->GetWidth() : 0;
  157. }
  158. ////////////////////////////////////////////////////////////
  159. unsigned int Window::GetHeight() const
  160. {
  161. return myWindow ? myWindow->GetHeight() : 0;
  162. }
  163. ////////////////////////////////////////////////////////////
  164. const ContextSettings& Window::GetSettings() const
  165. {
  166. static const ContextSettings empty(0, 0, 0);
  167. return myContext ? myContext->GetSettings() : empty;
  168. }
  169. ////////////////////////////////////////////////////////////
  170. bool Window::GetEvent(Event& event)
  171. {
  172. if (myWindow && myWindow->PopEvent(event, false))
  173. {
  174. return FilterEvent(event);
  175. }
  176. else
  177. {
  178. return false;
  179. }
  180. }
  181. ////////////////////////////////////////////////////////////
  182. bool Window::WaitEvent(Event& event)
  183. {
  184. if (myWindow && myWindow->PopEvent(event, true))
  185. {
  186. return FilterEvent(event);
  187. }
  188. else
  189. {
  190. return false;
  191. }
  192. }
  193. ////////////////////////////////////////////////////////////
  194. void Window::UseVerticalSync(bool enabled)
  195. {
  196. if (SetActive())
  197. myContext->UseVerticalSync(enabled);
  198. }
  199. ////////////////////////////////////////////////////////////
  200. void Window::ShowMouseCursor(bool show)
  201. {
  202. if (myWindow)
  203. myWindow->ShowMouseCursor(show);
  204. }
  205. ////////////////////////////////////////////////////////////
  206. void Window::SetCursorPosition(unsigned int x, unsigned int y)
  207. {
  208. if (myWindow)
  209. {
  210. // Keep coordinates for later checking (to reject the generated MouseMoved event)
  211. mySetCursorPosX = x;
  212. mySetCursorPosY = y;
  213. myWindow->SetCursorPosition(x, y);
  214. }
  215. }
  216. ////////////////////////////////////////////////////////////
  217. void Window::SetPosition(int x, int y)
  218. {
  219. if (myWindow)
  220. myWindow->SetPosition(x, y);
  221. }
  222. ////////////////////////////////////////////////////////////
  223. void Window::SetSize(unsigned int width, unsigned int height)
  224. {
  225. if (myWindow)
  226. myWindow->SetSize(width, height);
  227. }
  228. ////////////////////////////////////////////////////////////
  229. void Window::SetTitle(const std::string& title)
  230. {
  231. if (myWindow)
  232. myWindow->SetTitle(title);
  233. }
  234. ////////////////////////////////////////////////////////////
  235. void Window::Show(bool show)
  236. {
  237. if (myWindow)
  238. myWindow->Show(show);
  239. }
  240. ////////////////////////////////////////////////////////////
  241. void Window::EnableKeyRepeat(bool enabled)
  242. {
  243. if (myWindow)
  244. myWindow->EnableKeyRepeat(enabled);
  245. }
  246. ////////////////////////////////////////////////////////////
  247. void Window::SetIcon(unsigned int width, unsigned int height, const Uint8* pixels)
  248. {
  249. if (myWindow)
  250. myWindow->SetIcon(width, height, pixels);
  251. }
  252. ////////////////////////////////////////////////////////////
  253. bool Window::SetActive(bool active) const
  254. {
  255. if (myContext)
  256. {
  257. if (myContext->SetActive(active))
  258. {
  259. return true;
  260. }
  261. else
  262. {
  263. Err() << "Failed to activate the window's context" << std::endl;
  264. return false;
  265. }
  266. }
  267. else
  268. {
  269. return false;
  270. }
  271. }
  272. ////////////////////////////////////////////////////////////
  273. void Window::Display()
  274. {
  275. // Limit the framerate if needed
  276. if (myFramerateLimit > 0)
  277. {
  278. float remainingTime = 1.f / myFramerateLimit - myClock.GetElapsedTime();
  279. if (remainingTime > 0)
  280. Sleep(remainingTime);
  281. }
  282. // Measure the time elapsed since last frame
  283. myLastFrameTime = myClock.GetElapsedTime();
  284. myClock.Reset();
  285. // Display the backbuffer on screen
  286. if (SetActive())
  287. myContext->Display();
  288. }
  289. ////////////////////////////////////////////////////////////
  290. const Input& Window::GetInput() const
  291. {
  292. return myInput;
  293. }
  294. ////////////////////////////////////////////////////////////
  295. void Window::SetFramerateLimit(unsigned int limit)
  296. {
  297. myFramerateLimit = limit;
  298. }
  299. ////////////////////////////////////////////////////////////
  300. float Window::GetFrameTime() const
  301. {
  302. return myLastFrameTime;
  303. }
  304. ////////////////////////////////////////////////////////////
  305. void Window::SetJoystickThreshold(float threshold)
  306. {
  307. if (myWindow)
  308. myWindow->SetJoystickThreshold(threshold);
  309. }
  310. ////////////////////////////////////////////////////////////
  311. WindowHandle Window::GetSystemHandle() const
  312. {
  313. return myWindow ? myWindow->GetSystemHandle() : 0;
  314. }
  315. ////////////////////////////////////////////////////////////
  316. void Window::OnCreate()
  317. {
  318. // Nothing by default
  319. }
  320. ////////////////////////////////////////////////////////////
  321. void Window::OnResize()
  322. {
  323. // Nothing by default
  324. }
  325. ////////////////////////////////////////////////////////////
  326. bool Window::FilterEvent(const Event& event)
  327. {
  328. // Notify the input object
  329. myInput.OnEvent(event);
  330. // Notify resize events to the derived class
  331. if (event.Type == Event::Resized)
  332. OnResize();
  333. // Don't forward to the user MouseMove events generated by SetCursorPosition
  334. if ((event.Type == Event::MouseMoved) &&
  335. (event.MouseMove.X == mySetCursorPosX) &&
  336. (event.MouseMove.Y == mySetCursorPosY))
  337. {
  338. mySetCursorPosX = 0xFFFF;
  339. mySetCursorPosY = 0xFFFF;
  340. return false;
  341. }
  342. return true;
  343. }
  344. ////////////////////////////////////////////////////////////
  345. void Window::Initialize()
  346. {
  347. // Setup default behaviours (to get a consistent behaviour across different implementations)
  348. Show(true);
  349. UseVerticalSync(false);
  350. ShowMouseCursor(true);
  351. EnableKeyRepeat(true);
  352. // Reset frame time
  353. myClock.Reset();
  354. myLastFrameTime = 0.f;
  355. // Activate the window
  356. SetActive();
  357. // Notify the derived class
  358. OnCreate();
  359. }
  360. } // namespace sf