summaryrefslogtreecommitdiff
path: root/src/SFML/Window/Win32/WindowImplWin32.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/SFML/Window/Win32/WindowImplWin32.cpp')
-rwxr-xr-xsrc/SFML/Window/Win32/WindowImplWin32.cpp226
1 files changed, 99 insertions, 127 deletions
diff --git a/src/SFML/Window/Win32/WindowImplWin32.cpp b/src/SFML/Window/Win32/WindowImplWin32.cpp
index 9148774..506cb73 100755
--- a/src/SFML/Window/Win32/WindowImplWin32.cpp
+++ b/src/SFML/Window/Win32/WindowImplWin32.cpp
@@ -36,13 +36,16 @@
#include <iostream>
#include <vector>
-// Old versions of MinGW lack the definition of XBUTTON1 and XBUTTON2
+// MinGW lacks the definition of some Win32 constants
#ifndef XBUTTON1
#define XBUTTON1 0x0001
#endif
#ifndef XBUTTON2
#define XBUTTON2 0x0002
#endif
+#ifndef MAPVK_VK_TO_VSC
+ #define MAPVK_VK_TO_VSC (0)
+#endif
namespace sf
@@ -150,10 +153,12 @@ myIsCursorIn (false)
RegisterWindowClass();
// Compute position and size
- int Left = (GetDeviceCaps(GetDC(NULL), HORZRES) - Mode.Width) / 2;
- int Top = (GetDeviceCaps(GetDC(NULL), VERTRES) - Mode.Height) / 2;
+ HDC ScreenDC = GetDC(NULL);
+ int Left = (GetDeviceCaps(ScreenDC, HORZRES) - Mode.Width) / 2;
+ int Top = (GetDeviceCaps(ScreenDC, VERTRES) - Mode.Height) / 2;
int Width = myWidth = Mode.Width;
int Height = myHeight = Mode.Height;
+ ReleaseDC(NULL, ScreenDC);
// Choose the window style according to the Style parameter
DWORD Win32Style = WS_VISIBLE;
@@ -268,7 +273,7 @@ void WindowImplWin32::ProcessEvents()
if (!myCallback)
{
MSG Message;
- while (PeekMessage(&Message, myHandle, 0, 0, PM_REMOVE))
+ while (PeekMessage(&Message, NULL, 0, 0, PM_REMOVE))
{
TranslateMessage(&Message);
DispatchMessage(&Message);
@@ -476,20 +481,16 @@ void WindowImplWin32::SwitchToFullscreen(const VideoMode& Mode)
return;
}
- // Change window style (no border, no titlebar, ...)
- SetWindowLong(myHandle, GWL_STYLE, WS_POPUP);
+ // Make the window flags compatible with fullscreen mode
+ SetWindowLong(myHandle, GWL_STYLE, WS_POPUP | WS_CLIPCHILDREN | WS_CLIPSIBLINGS);
SetWindowLong(myHandle, GWL_EXSTYLE, WS_EX_APPWINDOW);
- // And resize it so that it fits the entire screen
+ // Resize the window so that it fits the entire screen
SetWindowPos(myHandle, HWND_TOP, 0, 0, Mode.Width, Mode.Height, SWP_FRAMECHANGED);
ShowWindow(myHandle, SW_SHOW);
// Set "this" as the current fullscreen window
ourFullscreenWindow = this;
-
- // SetPixelFormat can fail (really ?) if window style doesn't contain these flags
- long Style = GetWindowLong(myHandle, GWL_STYLE);
- SetWindowLong(myHandle, GWL_STYLE, Style | WS_CLIPCHILDREN | WS_CLIPSIBLINGS);
}
@@ -512,68 +513,76 @@ void WindowImplWin32::CreateContext(const VideoMode& Mode, WindowSettings& Param
{
// Get the wglChoosePixelFormatARB function (it is an extension)
PFNWGLCHOOSEPIXELFORMATARBPROC wglChoosePixelFormatARB = reinterpret_cast<PFNWGLCHOOSEPIXELFORMATARBPROC>(wglGetProcAddress("wglChoosePixelFormatARB"));
-
- // Define the basic attributes we want for our window
- int IntAttributes[] =
- {
- WGL_DRAW_TO_WINDOW_ARB, GL_TRUE,
- WGL_SUPPORT_OPENGL_ARB, GL_TRUE,
- WGL_ACCELERATION_ARB, WGL_FULL_ACCELERATION_ARB,
- WGL_DOUBLE_BUFFER_ARB, GL_TRUE,
- WGL_SAMPLE_BUFFERS_ARB, (Params.AntialiasingLevel ? GL_TRUE : GL_FALSE),
- WGL_SAMPLES_ARB, Params.AntialiasingLevel,
- 0, 0
- };
-
- // Let's check how many formats are supporting our requirements
- int Formats[128];
- UINT NbFormats;
- float FloatAttributes[] = {0, 0};
- bool IsValid = wglChoosePixelFormatARB(myDeviceContext, IntAttributes, FloatAttributes, sizeof(Formats) / sizeof(*Formats), Formats, &NbFormats) != 0;
- if (!IsValid || (NbFormats == 0))
+ if (wglChoosePixelFormatARB)
{
- if (Params.AntialiasingLevel > 2)
+ // Define the basic attributes we want for our window
+ int IntAttributes[] =
{
- // No format matching our needs : reduce the multisampling level
- std::cerr << "Failed to find a pixel format supporting "
- << Params.AntialiasingLevel << " antialiasing levels ; trying with 2 levels" << std::endl;
-
- Params.AntialiasingLevel = IntAttributes[1] = 2;
- IsValid = wglChoosePixelFormatARB(myDeviceContext, IntAttributes, FloatAttributes, sizeof(Formats) / sizeof(*Formats), Formats, &NbFormats) != 0;
- }
-
+ WGL_DRAW_TO_WINDOW_ARB, GL_TRUE,
+ WGL_SUPPORT_OPENGL_ARB, GL_TRUE,
+ WGL_ACCELERATION_ARB, WGL_FULL_ACCELERATION_ARB,
+ WGL_DOUBLE_BUFFER_ARB, GL_TRUE,
+ WGL_SAMPLE_BUFFERS_ARB, (Params.AntialiasingLevel ? GL_TRUE : GL_FALSE),
+ WGL_SAMPLES_ARB, Params.AntialiasingLevel,
+ 0, 0
+ };
+
+ // Let's check how many formats are supporting our requirements
+ int Formats[128];
+ UINT NbFormats;
+ float FloatAttributes[] = {0, 0};
+ bool IsValid = wglChoosePixelFormatARB(myDeviceContext, IntAttributes, FloatAttributes, sizeof(Formats) / sizeof(*Formats), Formats, &NbFormats) != 0;
if (!IsValid || (NbFormats == 0))
{
- // Cannot find any pixel format supporting multisampling ; disabling antialiasing
- std::cerr << "Failed to find a pixel format supporting antialiasing ; antialiasing will be disabled" << std::endl;
- Params.AntialiasingLevel = 0;
+ if (Params.AntialiasingLevel > 2)
+ {
+ // No format matching our needs : reduce the multisampling level
+ std::cerr << "Failed to find a pixel format supporting "
+ << Params.AntialiasingLevel << " antialiasing levels ; trying with 2 levels" << std::endl;
+
+ Params.AntialiasingLevel = IntAttributes[11] = 2;
+ IsValid = wglChoosePixelFormatARB(myDeviceContext, IntAttributes, FloatAttributes, sizeof(Formats) / sizeof(*Formats), Formats, &NbFormats) != 0;
+ }
+
+ if (!IsValid || (NbFormats == 0))
+ {
+ // Cannot find any pixel format supporting multisampling ; disabling antialiasing
+ std::cerr << "Failed to find a pixel format supporting antialiasing ; antialiasing will be disabled" << std::endl;
+ Params.AntialiasingLevel = 0;
+ }
}
- }
- // Get the best format among the returned ones
- if (IsValid && (NbFormats > 0))
- {
- int BestScore = 0xFFFF;
- for (UINT i = 0; i < NbFormats; ++i)
+ // Get the best format among the returned ones
+ if (IsValid && (NbFormats > 0))
{
- // Get the current format's attributes
- PIXELFORMATDESCRIPTOR Attribs;
- Attribs.nSize = sizeof(PIXELFORMATDESCRIPTOR);
- Attribs.nVersion = 1;
- DescribePixelFormat(myDeviceContext, Formats[i], sizeof(PIXELFORMATDESCRIPTOR), &Attribs);
-
- // Evaluate the current configuration
- int Color = Attribs.cRedBits + Attribs.cGreenBits + Attribs.cBlueBits + Attribs.cAlphaBits;
- int Score = EvaluateConfig(Mode, Params, Color, Attribs.cDepthBits, Attribs.cStencilBits, Params.AntialiasingLevel);
-
- // Keep it if it's better than the current best
- if (Score < BestScore)
+ int BestScore = 0xFFFF;
+ for (UINT i = 0; i < NbFormats; ++i)
{
- BestScore = Score;
- BestFormat = Formats[i];
+ // Get the current format's attributes
+ PIXELFORMATDESCRIPTOR Attribs;
+ Attribs.nSize = sizeof(PIXELFORMATDESCRIPTOR);
+ Attribs.nVersion = 1;
+ DescribePixelFormat(myDeviceContext, Formats[i], sizeof(PIXELFORMATDESCRIPTOR), &Attribs);
+
+ // Evaluate the current configuration
+ int Color = Attribs.cRedBits + Attribs.cGreenBits + Attribs.cBlueBits + Attribs.cAlphaBits;
+ int Score = EvaluateConfig(Mode, Params, Color, Attribs.cDepthBits, Attribs.cStencilBits, Params.AntialiasingLevel);
+
+ // Keep it if it's better than the current best
+ if (Score < BestScore)
+ {
+ BestScore = Score;
+ BestFormat = Formats[i];
+ }
}
}
}
+ else
+ {
+ // wglChoosePixelFormatARB not supported ; disabling antialiasing
+ std::cerr << "Antialiasing is not supported ; it will be disabled" << std::endl;
+ Params.AntialiasingLevel = 0;
+ }
}
// Find a pixel format with no antialiasing, if not needed or not supported
@@ -590,6 +599,7 @@ void WindowImplWin32::CreateContext(const VideoMode& Mode, WindowSettings& Param
PixelDescriptor.cColorBits = static_cast<BYTE>(Mode.BitsPerPixel);
PixelDescriptor.cDepthBits = static_cast<BYTE>(Params.DepthBits);
PixelDescriptor.cStencilBits = static_cast<BYTE>(Params.StencilBits);
+ PixelDescriptor.cAlphaBits = Mode.BitsPerPixel == 32 ? 8 : 0;
// Get the pixel format that best matches our requirements
BestFormat = ChoosePixelFormat(myDeviceContext, &PixelDescriptor);
@@ -745,10 +755,13 @@ void WindowImplWin32::ProcessEvent(UINT Message, WPARAM WParam, LPARAM LParam)
// Text event
case WM_CHAR :
{
- Event Evt;
- Evt.Type = Event::TextEntered;
- Evt.Text.Unicode = static_cast<Uint32>(WParam);
- SendEvent(Evt);
+ if (myKeyRepeatEnabled || ((LParam & (1 << 30)) == 0))
+ {
+ Event Evt;
+ Evt.Type = Event::TextEntered;
+ Evt.Text.Unicode = static_cast<Uint32>(WParam);
+ SendEvent(Evt);
+ }
break;
}
@@ -756,26 +769,15 @@ void WindowImplWin32::ProcessEvent(UINT Message, WPARAM WParam, LPARAM LParam)
case WM_KEYDOWN :
case WM_SYSKEYDOWN :
{
- if (myKeyRepeatEnabled || ((LParam & (1 << 30)) == 0))
+ if (myKeyRepeatEnabled || ((HIWORD(LParam) & KF_REPEAT) == 0))
{
Event Evt;
Evt.Type = Event::KeyPressed;
Evt.Key.Alt = HIWORD(GetAsyncKeyState(VK_MENU)) != 0;
Evt.Key.Control = HIWORD(GetAsyncKeyState(VK_CONTROL)) != 0;
Evt.Key.Shift = HIWORD(GetAsyncKeyState(VK_SHIFT)) != 0;
-
- if (WParam != VK_SHIFT)
- {
- Evt.Key.Code = VirtualKeyCodeToSF(WParam, LParam);
- SendEvent(Evt);
- }
- else
- {
- // Special case for shift, its state can't be retrieved directly
- Evt.Key.Code = GetShiftState(true);
- if (Evt.Key.Code != 0)
- SendEvent(Evt);
- }
+ Evt.Key.Code = VirtualKeyCodeToSF(WParam, LParam);
+ SendEvent(Evt);
}
break;
}
@@ -789,19 +791,8 @@ void WindowImplWin32::ProcessEvent(UINT Message, WPARAM WParam, LPARAM LParam)
Evt.Key.Alt = HIWORD(GetAsyncKeyState(VK_MENU)) != 0;
Evt.Key.Control = HIWORD(GetAsyncKeyState(VK_CONTROL)) != 0;
Evt.Key.Shift = HIWORD(GetAsyncKeyState(VK_SHIFT)) != 0;
-
- if (WParam != VK_SHIFT)
- {
- Evt.Key.Code = VirtualKeyCodeToSF(WParam, LParam);
- SendEvent(Evt);
- }
- else
- {
- // Special case for shift, its state can't be retrieved directly
- Evt.Key.Code = GetShiftState(false);
- if (Evt.Key.Code != 0)
- SendEvent(Evt);
- }
+ Evt.Key.Code = VirtualKeyCodeToSF(WParam, LParam);
+ SendEvent(Evt);
break;
}
@@ -954,46 +945,27 @@ void WindowImplWin32::ProcessEvent(UINT Message, WPARAM WParam, LPARAM LParam)
////////////////////////////////////////////////////////////
-/// Check the state of the shift keys on a key event,
-/// and return the corresponding SF key code
-////////////////////////////////////////////////////////////
-Key::Code WindowImplWin32::GetShiftState(bool KeyDown)
-{
- static bool LShiftPrevDown = false;
- static bool RShiftPrevDown = false;
-
- bool LShiftDown = (HIWORD(GetAsyncKeyState(VK_LSHIFT)) != 0);
- bool RShiftDown = (HIWORD(GetAsyncKeyState(VK_RSHIFT)) != 0);
-
- Key::Code Code = Key::Code(0);
- if (KeyDown)
- {
- if (!LShiftPrevDown && LShiftDown) Code = Key::LShift;
- else if (!RShiftPrevDown && RShiftDown) Code = Key::RShift;
- }
- else
- {
- if (LShiftPrevDown && !LShiftDown) Code = Key::LShift;
- else if (RShiftPrevDown && !RShiftDown) Code = Key::RShift;
- }
-
- LShiftPrevDown = LShiftDown;
- RShiftPrevDown = RShiftDown;
-
- return Code;
-}
-
-
-////////////////////////////////////////////////////////////
/// Convert a Win32 virtual key code to a SFML key code
////////////////////////////////////////////////////////////
Key::Code WindowImplWin32::VirtualKeyCodeToSF(WPARAM VirtualKey, LPARAM Flags)
{
switch (VirtualKey)
{
- // VK_SHIFT is handled by the GetShiftState function
- case VK_MENU : return (Flags & (1 << 24)) ? Key::RAlt : Key::LAlt;
- case VK_CONTROL : return (Flags & (1 << 24)) ? Key::RControl : Key::LControl;
+ // Check the scancode to distinguish between left and right shift
+ case VK_SHIFT :
+ {
+ static UINT LShift = MapVirtualKey(VK_LSHIFT, MAPVK_VK_TO_VSC);
+ UINT scancode = (Flags & (0xFF << 16)) >> 16;
+ return scancode == LShift ? Key::LShift : Key::RShift;
+ }
+
+ // Check the "extended" flag to distinguish between left and right alt
+ case VK_MENU : return (HIWORD(Flags) & KF_EXTENDED) ? Key::RAlt : Key::LAlt;
+
+ // Check the "extended" flag to distinguish between left and right control
+ case VK_CONTROL : return (HIWORD(Flags) & KF_EXTENDED) ? Key::RControl : Key::LControl;
+
+ // Other keys are reported properly
case VK_LWIN : return Key::LSystem;
case VK_RWIN : return Key::RSystem;
case VK_APPS : return Key::Menu;