mirror of
https://github.com/panda3d/panda3d.git
synced 2025-10-05 03:15:07 -04:00
more fixes from Gogg: Windows 7 fullscreen workaround
This commit is contained in:
parent
6a5dcc40e8
commit
c172d80a41
@ -13,7 +13,7 @@
|
|||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: TextFont::get_face
|
// Function: FreetypeFace::get_face
|
||||||
// Access: Published
|
// Access: Published
|
||||||
// Description: Retrieves the internal freetype face.
|
// Description: Retrieves the internal freetype face.
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
@ -23,11 +23,14 @@ get_face() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: TextFont::set_face
|
// Function: FreetypeFace::set_face
|
||||||
// Access: Published
|
// Access: Published
|
||||||
// Description: Sets the internal freetype face.
|
// Description: Sets the internal freetype face.
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
INLINE void FreetypeFace::
|
INLINE void FreetypeFace::
|
||||||
set_face(FT_Face face) {
|
set_face(FT_Face face) {
|
||||||
|
if (_face != NULL){
|
||||||
|
FT_Done_Face(_face);
|
||||||
|
}
|
||||||
_face = face;
|
_face = face;
|
||||||
}
|
}
|
||||||
|
@ -42,7 +42,7 @@ FreetypeFont::
|
|||||||
FreetypeFont() {
|
FreetypeFont() {
|
||||||
_font_loaded = false;
|
_font_loaded = false;
|
||||||
|
|
||||||
_face = new FreetypeFace();
|
_face = NULL;
|
||||||
|
|
||||||
_point_size = text_point_size;
|
_point_size = text_point_size;
|
||||||
_requested_pixels_per_unit = text_pixels_per_unit;
|
_requested_pixels_per_unit = text_pixels_per_unit;
|
||||||
@ -91,6 +91,7 @@ load_font(const Filename &font_filename, int face_index) {
|
|||||||
(const FT_Byte *)_raw_font_data.data(),
|
(const FT_Byte *)_raw_font_data.data(),
|
||||||
_raw_font_data.length(),
|
_raw_font_data.length(),
|
||||||
face_index, &face);
|
face_index, &face);
|
||||||
|
_face = new FreetypeFace();
|
||||||
_face->set_face(face);
|
_face->set_face(face);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -135,6 +136,7 @@ load_font(const char *font_data, int data_length, int face_index) {
|
|||||||
error = FT_New_Memory_Face(_ft_library,
|
error = FT_New_Memory_Face(_ft_library,
|
||||||
(const FT_Byte *)font_data, data_length,
|
(const FT_Byte *)font_data, data_length,
|
||||||
face_index, &face);
|
face_index, &face);
|
||||||
|
_face = new FreetypeFace();
|
||||||
_face->set_face(face);
|
_face->set_face(face);
|
||||||
|
|
||||||
if (error == FT_Err_Unknown_File_Format) {
|
if (error == FT_Err_Unknown_File_Format) {
|
||||||
|
@ -379,12 +379,7 @@ open_window() {
|
|||||||
// even before it gives us a handle. Warning: this is not thread
|
// even before it gives us a handle. Warning: this is not thread
|
||||||
// safe!
|
// safe!
|
||||||
_creating_window = this;
|
_creating_window = this;
|
||||||
bool opened;
|
bool opened = open_graphic_window(is_fullscreen());
|
||||||
if (is_fullscreen()) {
|
|
||||||
opened = open_fullscreen_window();
|
|
||||||
} else {
|
|
||||||
opened = open_regular_window();
|
|
||||||
}
|
|
||||||
_creating_window = (WinGraphicsWindow *)NULL;
|
_creating_window = (WinGraphicsWindow *)NULL;
|
||||||
|
|
||||||
if (!opened) {
|
if (!opened) {
|
||||||
@ -737,96 +732,12 @@ support_overlay_window(bool) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: WinGraphicsWindow::open_fullscreen_window
|
// Function: WinGraphicsWindow::open_graphic_window
|
||||||
// Access: Private
|
// Access: Private
|
||||||
// Description: Creates a fullscreen-style window.
|
// Description: Creates a regular or fullscreen window.
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
bool WinGraphicsWindow::
|
bool WinGraphicsWindow::
|
||||||
open_fullscreen_window()
|
open_graphic_window(bool fullscreen) {
|
||||||
{
|
|
||||||
// from MSDN:
|
|
||||||
// An OpenGL window has its own pixel format. Because of this, only
|
|
||||||
// device contexts retrieved for the client area of an OpenGL
|
|
||||||
// window are allowed to draw into the window. As a result, an
|
|
||||||
// OpenGL window should be created with the WS_CLIPCHILDREN and
|
|
||||||
// WS_CLIPSIBLINGS styles. Additionally, the window class attribute
|
|
||||||
// should not include the CS_PARENTDC style.
|
|
||||||
DWORD window_style =
|
|
||||||
WS_POPUP | WS_SYSMENU | WS_CLIPCHILDREN | WS_CLIPSIBLINGS;
|
|
||||||
|
|
||||||
if (!_properties.has_size()) {
|
|
||||||
// Just pick a stupid default size if one isn't specified.
|
|
||||||
_properties.set_size(640, 480);
|
|
||||||
}
|
|
||||||
|
|
||||||
// No parent window for a fullscreen window.
|
|
||||||
_parent_window_handle = NULL;
|
|
||||||
|
|
||||||
HWND hDesktopWindow = GetDesktopWindow();
|
|
||||||
HDC scrnDC = GetDC(hDesktopWindow);
|
|
||||||
DWORD cur_bitdepth = GetDeviceCaps(scrnDC, BITSPIXEL);
|
|
||||||
// DWORD drvr_ver = GetDeviceCaps(scrnDC, DRIVERVERSION);
|
|
||||||
// DWORD cur_scrnwidth = GetDeviceCaps(scrnDC, HORZRES);
|
|
||||||
// DWORD cur_scrnheight = GetDeviceCaps(scrnDC, VERTRES);
|
|
||||||
ReleaseDC(hDesktopWindow, scrnDC);
|
|
||||||
|
|
||||||
DWORD dwWidth = _properties.get_x_size();
|
|
||||||
DWORD dwHeight = _properties.get_y_size();
|
|
||||||
DWORD dwFullScreenBitDepth = cur_bitdepth;
|
|
||||||
|
|
||||||
reconsider_fullscreen_size(dwWidth, dwHeight, dwFullScreenBitDepth);
|
|
||||||
if (!find_acceptable_display_mode(dwWidth, dwHeight, dwFullScreenBitDepth,
|
|
||||||
_fullscreen_display_mode)) {
|
|
||||||
windisplay_cat.error()
|
|
||||||
<< "Videocard has no supported display resolutions at specified res ("
|
|
||||||
<< dwWidth << " x " << dwHeight << " x " << dwFullScreenBitDepth <<")\n";
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
string title;
|
|
||||||
if (_properties.has_title()) {
|
|
||||||
title = _properties.get_title();
|
|
||||||
}
|
|
||||||
|
|
||||||
// I'd prefer to CreateWindow after DisplayChange in case it messes
|
|
||||||
// up GL somehow, but I need the window's black background to cover
|
|
||||||
// up the desktop during the mode change
|
|
||||||
const WindowClass &wclass = register_window_class(_properties);
|
|
||||||
HINSTANCE hinstance = GetModuleHandle(NULL);
|
|
||||||
|
|
||||||
_hWnd = CreateWindow(wclass._name.c_str(), title.c_str(), window_style,
|
|
||||||
0, 0, dwWidth, dwHeight,
|
|
||||||
hDesktopWindow, NULL, hinstance, 0);
|
|
||||||
if (!_hWnd) {
|
|
||||||
windisplay_cat.error()
|
|
||||||
<< "CreateWindow() failed!" << endl;
|
|
||||||
show_error_message();
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
int chg_result = ChangeDisplaySettings(&_fullscreen_display_mode,
|
|
||||||
CDS_FULLSCREEN);
|
|
||||||
if (chg_result != DISP_CHANGE_SUCCESSFUL) {
|
|
||||||
windisplay_cat.error()
|
|
||||||
<< "ChangeDisplaySettings failed (error code: "
|
|
||||||
<< chg_result << ") for specified res (" << dwWidth
|
|
||||||
<< " x " << dwHeight << " x " << dwFullScreenBitDepth
|
|
||||||
<< "), " << _fullscreen_display_mode.dmDisplayFrequency << "Hz\n";
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
_properties.set_origin(0, 0);
|
|
||||||
_properties.set_size(dwWidth, dwHeight);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
|
||||||
// Function: WinGraphicsWindow::open_regular_window
|
|
||||||
// Access: Private
|
|
||||||
// Description: Creates a non-fullscreen window, on the desktop.
|
|
||||||
////////////////////////////////////////////////////////////////////
|
|
||||||
bool WinGraphicsWindow::
|
|
||||||
open_regular_window() {
|
|
||||||
// from MSDN:
|
// from MSDN:
|
||||||
// An OpenGL window has its own pixel format. Because of this, only
|
// An OpenGL window has its own pixel format. Because of this, only
|
||||||
// device contexts retrieved for the client area of an OpenGL
|
// device contexts retrieved for the client area of an OpenGL
|
||||||
@ -837,7 +748,9 @@ open_regular_window() {
|
|||||||
DWORD window_style =
|
DWORD window_style =
|
||||||
WS_POPUP | WS_CLIPCHILDREN | WS_CLIPSIBLINGS;
|
WS_POPUP | WS_CLIPCHILDREN | WS_CLIPSIBLINGS;
|
||||||
|
|
||||||
if (!_properties.get_undecorated()) {
|
if (fullscreen){
|
||||||
|
window_style |= WS_SYSMENU;
|
||||||
|
} else if (!_properties.get_undecorated()) {
|
||||||
window_style |= (WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX);
|
window_style |= (WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX);
|
||||||
|
|
||||||
if (!_properties.get_fixed_size()) {
|
if (!_properties.get_fixed_size()) {
|
||||||
@ -847,20 +760,30 @@ open_regular_window() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
string title;
|
||||||
|
if (_properties.has_title()) {
|
||||||
|
title = _properties.get_title();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!_properties.has_size()) {
|
||||||
|
//Just pick a conservative default size if one isn't specified.
|
||||||
|
_properties.set_size(640, 480);
|
||||||
|
}
|
||||||
|
|
||||||
int x_origin = 0;
|
int x_origin = 0;
|
||||||
int y_origin = 0;
|
int y_origin = 0;
|
||||||
if (_properties.has_origin()) {
|
if (!fullscreen && _properties.has_origin()) {
|
||||||
x_origin = _properties.get_x_origin();
|
x_origin = _properties.get_x_origin();
|
||||||
y_origin = _properties.get_y_origin();
|
y_origin = _properties.get_y_origin();
|
||||||
}
|
}
|
||||||
|
|
||||||
int x_size = 100;
|
int x_size = _properties.get_x_size();
|
||||||
int y_size = 100;
|
int y_size = _properties.get_y_size();
|
||||||
if (_properties.has_size()) {
|
|
||||||
x_size = _properties.get_x_size();
|
|
||||||
y_size = _properties.get_y_size();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
int clientAreaWidth = x_size;
|
||||||
|
int clientAreaHeight = y_size;
|
||||||
|
|
||||||
|
if (!fullscreen){
|
||||||
RECT win_rect;
|
RECT win_rect;
|
||||||
SetRect(&win_rect, x_origin, y_origin,
|
SetRect(&win_rect, x_origin, y_origin,
|
||||||
x_origin + x_size, y_origin + y_size);
|
x_origin + x_size, y_origin + y_size);
|
||||||
@ -872,11 +795,6 @@ open_regular_window() {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
string title;
|
|
||||||
if (_properties.has_title()) {
|
|
||||||
title = _properties.get_title();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (_properties.has_origin()) {
|
if (_properties.has_origin()) {
|
||||||
x_origin = win_rect.left;
|
x_origin = win_rect.left;
|
||||||
y_origin = win_rect.top;
|
y_origin = win_rect.top;
|
||||||
@ -885,12 +803,16 @@ open_regular_window() {
|
|||||||
x_origin = CW_USEDEFAULT;
|
x_origin = CW_USEDEFAULT;
|
||||||
y_origin = CW_USEDEFAULT;
|
y_origin = CW_USEDEFAULT;
|
||||||
}
|
}
|
||||||
|
clientAreaWidth = win_rect.right - win_rect.left;
|
||||||
|
clientAreaHeight = win_rect.bottom - win_rect.top;
|
||||||
|
}
|
||||||
|
|
||||||
const WindowClass &wclass = register_window_class(_properties);
|
const WindowClass &wclass = register_window_class(_properties);
|
||||||
HINSTANCE hinstance = GetModuleHandle(NULL);
|
HINSTANCE hinstance = GetModuleHandle(NULL);
|
||||||
|
|
||||||
_hparent = NULL;
|
_hparent = NULL;
|
||||||
|
|
||||||
|
if (!fullscreen){
|
||||||
WindowHandle *window_handle = _properties.get_parent_window();
|
WindowHandle *window_handle = _properties.get_parent_window();
|
||||||
if (window_handle != NULL) {
|
if (window_handle != NULL) {
|
||||||
windisplay_cat.info()
|
windisplay_cat.info()
|
||||||
@ -910,19 +832,21 @@ open_regular_window() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
_parent_window_handle = window_handle;
|
_parent_window_handle = window_handle;
|
||||||
|
} else {
|
||||||
|
_parent_window_handle = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
if (!_hparent) {
|
if (!_hparent) { // This can be a regular window or a fullscreen window
|
||||||
_hWnd = CreateWindow(wclass._name.c_str(), title.c_str(), window_style,
|
_hWnd = CreateWindow(wclass._name.c_str(), title.c_str(), window_style,
|
||||||
x_origin, y_origin,
|
x_origin, y_origin,
|
||||||
win_rect.right - win_rect.left,
|
clientAreaWidth,
|
||||||
win_rect.bottom - win_rect.top,
|
clientAreaHeight,
|
||||||
NULL, NULL, hinstance, 0);
|
NULL, NULL, hinstance, 0);
|
||||||
|
} else { // This is a regular window with a parent
|
||||||
} else {
|
|
||||||
x_origin = 0;
|
x_origin = 0;
|
||||||
y_origin = 0;
|
y_origin = 0;
|
||||||
|
|
||||||
if (_properties.has_origin()) {
|
if (!fullscreen && _properties.has_origin()) {
|
||||||
x_origin = _properties.get_x_origin();
|
x_origin = _properties.get_x_origin();
|
||||||
y_origin = _properties.get_y_origin();
|
y_origin = _properties.get_y_origin();
|
||||||
}
|
}
|
||||||
@ -954,6 +878,51 @@ open_regular_window() {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// I'd prefer to CreateWindow after DisplayChange in case it messes
|
||||||
|
// up GL somehow, but I need the window's black background to cover
|
||||||
|
// up the desktop during the mode change.
|
||||||
|
|
||||||
|
if (fullscreen){
|
||||||
|
HWND hDesktopWindow = GetDesktopWindow();
|
||||||
|
HDC scrnDC = GetDC(hDesktopWindow);
|
||||||
|
DWORD cur_bitdepth = GetDeviceCaps(scrnDC, BITSPIXEL);
|
||||||
|
// DWORD drvr_ver = GetDeviceCaps(scrnDC, DRIVERVERSION);
|
||||||
|
// DWORD cur_scrnwidth = GetDeviceCaps(scrnDC, HORZRES);
|
||||||
|
// DWORD cur_scrnheight = GetDeviceCaps(scrnDC, VERTRES);
|
||||||
|
ReleaseDC(hDesktopWindow, scrnDC);
|
||||||
|
|
||||||
|
DWORD dwWidth = _properties.get_x_size();
|
||||||
|
DWORD dwHeight = _properties.get_y_size();
|
||||||
|
DWORD dwFullScreenBitDepth = cur_bitdepth;
|
||||||
|
|
||||||
|
DEVMODE dm;
|
||||||
|
reconsider_fullscreen_size(dwWidth, dwHeight, dwFullScreenBitDepth);
|
||||||
|
if (!find_acceptable_display_mode(dwWidth, dwHeight, dwFullScreenBitDepth, dm)) {
|
||||||
|
windisplay_cat.error()
|
||||||
|
<< "Videocard has no supported display resolutions at specified res ("
|
||||||
|
<< dwWidth << " x " << dwHeight << " x " << dwFullScreenBitDepth <<")\n";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
dm.dmPelsWidth = dwWidth;
|
||||||
|
dm.dmPelsHeight = dwHeight;
|
||||||
|
dm.dmBitsPerPel = dwFullScreenBitDepth;
|
||||||
|
int chg_result = ChangeDisplaySettings(&dm, CDS_FULLSCREEN);
|
||||||
|
|
||||||
|
if (chg_result != DISP_CHANGE_SUCCESSFUL) {
|
||||||
|
windisplay_cat.error()
|
||||||
|
<< "ChangeDisplaySettings failed (error code: "
|
||||||
|
<< chg_result << ") for specified res (" << dwWidth
|
||||||
|
<< " x " << dwHeight << " x " << dwFullScreenBitDepth
|
||||||
|
<< "), " << _fullscreen_display_mode.dmDisplayFrequency << "Hz\n";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
_properties.set_origin(0, 0);
|
||||||
|
_properties.set_size(dwWidth, dwHeight);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2165,7 +2134,21 @@ find_acceptable_display_mode(DWORD dwWidth, DWORD dwHeight, DWORD bpp,
|
|||||||
|
|
||||||
if ((dm.dmPelsWidth == dwWidth) && (dm.dmPelsHeight == dwHeight) &&
|
if ((dm.dmPelsWidth == dwWidth) && (dm.dmPelsHeight == dwHeight) &&
|
||||||
(dm.dmBitsPerPel == bpp)) {
|
(dm.dmBitsPerPel == bpp)) {
|
||||||
|
cout << "[FS FOUND] " << dwWidth << "x" << dwHeight << "@" << bpp << endl;
|
||||||
|
// We want to modify the current DEVMODE rather than using a fresh one in order
|
||||||
|
// to work around a Windows 7 bug.
|
||||||
|
ZeroMemory(&dm, sizeof(dm));
|
||||||
|
dm.dmSize = sizeof(dm);
|
||||||
|
if (0 != EnumDisplaySettings(NULL, ENUM_CURRENT_SETTINGS, &dm)){
|
||||||
|
dm.dmPelsWidth = dwWidth;
|
||||||
|
dm.dmPelsHeight = dwHeight;
|
||||||
|
dm.dmBitsPerPel = bpp;
|
||||||
return true;
|
return true;
|
||||||
|
} else {
|
||||||
|
windisplay_cat.error()
|
||||||
|
<< "Couldn't retrieve active device mode.\n";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
modenum++;
|
modenum++;
|
||||||
}
|
}
|
||||||
|
@ -89,8 +89,7 @@ protected:
|
|||||||
virtual void support_overlay_window(bool flag);
|
virtual void support_overlay_window(bool flag);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool open_fullscreen_window();
|
bool open_graphic_window(bool fullscreen);
|
||||||
bool open_regular_window();
|
|
||||||
void adjust_z_order();
|
void adjust_z_order();
|
||||||
void adjust_z_order(WindowProperties::ZOrder last_z_order,
|
void adjust_z_order(WindowProperties::ZOrder last_z_order,
|
||||||
WindowProperties::ZOrder this_z_order);
|
WindowProperties::ZOrder this_z_order);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user