Add window.displayMode for fullscreen display mode switching

This commit is contained in:
Joshua Granick
2017-02-28 11:32:55 -08:00
parent 314e020428
commit 81c4926802
14 changed files with 350 additions and 24 deletions

View File

@@ -7,6 +7,7 @@ import flash.Lib;
import lime.app.Application;
import lime.graphics.Image;
import lime.system.Display;
import lime.system.DisplayMode;
import lime.system.System;
import lime.ui.Window;
@@ -67,6 +68,20 @@ class FlashWindow {
}
public function getDisplayMode ():DisplayMode {
return System.getDisplay (0).currentMode;
}
public function setDisplayMode (value:DisplayMode):DisplayMode {
return value;
}
public function getEnableTextEvents ():Bool {
return enableTextEvents;

View File

@@ -15,6 +15,7 @@ import js.Browser;
import lime.app.Application;
import lime.graphics.Image;
import lime.system.Display;
import lime.system.DisplayMode;
import lime.system.System;
import lime.system.Clipboard;
import lime.ui.Gamepad;
@@ -243,6 +244,20 @@ class HTML5Window {
}
public function getDisplayMode ():DisplayMode {
return System.getDisplay (0).currentMode;
}
public function setDisplayMode (value:DisplayMode):DisplayMode {
return value;
}
public function getEnableTextEvents ():Bool {
return enableTextEvents;

View File

@@ -137,6 +137,7 @@ class NativeCFFI {
@:cffi private static function lime_window_create (application:Dynamic, width:Int, height:Int, flags:Int, title:String):Dynamic;
@:cffi private static function lime_window_focus (handle:Dynamic):Void;
@:cffi private static function lime_window_get_display (handle:Dynamic):Int;
@:cffi private static function lime_window_get_display_mode (handle:Dynamic):Dynamic;
@:cffi private static function lime_window_get_enable_text_events (handle:Dynamic):Bool;
@:cffi private static function lime_window_get_height (handle:Dynamic):Int;
@:cffi private static function lime_window_get_id (handle:Dynamic):Int;
@@ -146,6 +147,7 @@ class NativeCFFI {
@:cffi private static function lime_window_move (handle:Dynamic, x:Int, y:Int):Void;
@:cffi private static function lime_window_resize (handle:Dynamic, width:Int, height:Int):Void;
@:cffi private static function lime_window_set_borderless (handle:Dynamic, borderless:Bool):Bool;
@:cffi private static function lime_window_set_display_mode (handle:Dynamic, displayMode:Dynamic):Dynamic;
@:cffi private static function lime_window_set_enable_text_events (handle:Dynamic, enabled:Bool):Void;
@:cffi private static function lime_window_set_fullscreen (handle:Dynamic, fullscreen:Bool):Bool;
@:cffi private static function lime_window_set_icon (handle:Dynamic, buffer:Dynamic):Void;

View File

@@ -7,6 +7,7 @@ import lime.graphics.Image;
import lime.graphics.ImageBuffer;
import lime.math.Vector2;
import lime.system.Display;
import lime.system.DisplayMode;
import lime.system.System;
import lime.ui.Window;
@@ -17,6 +18,7 @@ import lime.ui.Window;
@:access(lime._backend.native.NativeCFFI)
@:access(lime.app.Application)
@:access(lime.system.DisplayMode)
@:access(lime.ui.Window)
@@ -26,6 +28,7 @@ class NativeWindow {
public var handle:Dynamic;
private var closing:Bool;
private var displayMode:DisplayMode;
private var parent:Window;
@@ -33,6 +36,8 @@ class NativeWindow {
this.parent = parent;
displayMode = new DisplayMode (0, 0, 0, 0);
}
@@ -172,6 +177,44 @@ class NativeWindow {
}
public function getDisplayMode ():DisplayMode {
if (handle != null) {
#if !macro
var data:Dynamic = NativeCFFI.lime_window_get_display_mode (handle);
displayMode.width = data.width;
displayMode.height = data.height;
displayMode.pixelFormat = data.pixelFormat;
displayMode.refreshRate = data.refreshRate;
#end
}
return displayMode;
}
public function setDisplayMode (value:DisplayMode):DisplayMode {
if (handle != null) {
#if !macro
var data:Dynamic = NativeCFFI.lime_window_set_display_mode (handle, value);
displayMode.width = data.width;
displayMode.height = data.height;
displayMode.pixelFormat = data.pixelFormat;
displayMode.refreshRate = data.refreshRate;
#end
}
return displayMode;
}
public function getEnableTextEvents ():Bool {
if (handle != null) {

View File

@@ -118,16 +118,22 @@ class System {
}
if (Reflect.hasField (displayInfo, "currentMode")) {
var mode = displayInfo.currentMode;
var currentMode = new DisplayMode (mode.width, mode.height, mode.refreshRate, mode.pixelFormat);
display.currentMode = display.supportedModes[displayInfo.currentMode];
for (mode in display.supportedModes) {
} else {
if (currentMode.pixelFormat == mode.pixelFormat && currentMode.width == mode.width && currentMode.height == mode.height && currentMode.refreshRate == mode.refreshRate) {
display.currentMode = new DisplayMode (0, 0, 60, ARGB32);
currentMode = mode;
break;
}
}
display.currentMode = currentMode;
return display;
}

View File

@@ -7,6 +7,7 @@ import lime.app.Event;
import lime.graphics.Image;
import lime.graphics.Renderer;
import lime.system.Display;
import lime.system.DisplayMode;
#if openfl
import openfl.display.Stage;
@@ -29,6 +30,7 @@ class Window {
public var borderless (get, set):Bool;
public var config:WindowConfig;
public var display (get, null):Display;
public var displayMode (get, set):DisplayMode;
public var enableTextEvents (get, set):Bool;
public var fullscreen (get, set):Bool;
public var height (get, set):Int;
@@ -414,6 +416,20 @@ class Window {
}
@:noCompletion private function get_displayMode ():DisplayMode {
return backend.getDisplayMode ();
}
@:noCompletion private function set_displayMode (value:DisplayMode):DisplayMode {
return backend.setDisplayMode (value);
}
@:noCompletion private inline function get_borderless ():Bool {
return __borderless;

View File

@@ -249,6 +249,7 @@
<file name="src/media/containers/WAV.cpp" />
<file name="src/media/AudioBuffer.cpp" />
<file name="src/system/CFFIPointer.cpp" />
<file name="src/system/DisplayMode.cpp" />
<file name="src/system/JNI.cpp" if="android" />
<file name="src/system/Locale.cpp" unless="mac || ios" />
<file name="src/system/Locale.mm" if="mac || ios" />

View File

@@ -0,0 +1,33 @@
#ifndef LIME_SYSTEM_DISPLAY_MODE_H
#define LIME_SYSTEM_DISPLAY_MODE_H
#include <hx/CFFI.h>
#include <graphics/PixelFormat.h>
namespace lime {
class DisplayMode {
public:
DisplayMode ();
DisplayMode (value DisplayMode);
DisplayMode (int width, int height, PixelFormat pixelFormat, int refreshRate);
value Value ();
int height;
PixelFormat pixelFormat;
int refreshRate;
int width;
};
}
#endif

View File

@@ -8,6 +8,7 @@
#include <app/Application.h>
#include <graphics/ImageBuffer.h>
#include <system/DisplayMode.h>
#include <stdint.h>
@@ -25,6 +26,7 @@ namespace lime {
virtual void Close () = 0;
virtual void Focus () = 0;
virtual int GetDisplay () = 0;
virtual void GetDisplayMode (DisplayMode* displayMode) = 0;
virtual bool GetEnableTextEvents () = 0;
virtual int GetHeight () = 0;
virtual uint32_t GetID () = 0;
@@ -34,6 +36,7 @@ namespace lime {
virtual void Move (int x, int y) = 0;
virtual void Resize (int width, int height) = 0;
virtual bool SetBorderless (bool borderless) = 0;
virtual void SetDisplayMode (DisplayMode* displayMode) = 0;
virtual void SetEnableTextEvents (bool enable) = 0;
virtual bool SetFullscreen (bool fullscreen) = 0;
virtual void SetIcon (ImageBuffer *imageBuffer) = 0;

View File

@@ -1564,6 +1564,16 @@ namespace lime {
}
value lime_window_get_display_mode (value window) {
Window* targetWindow = (Window*)val_data (window);
DisplayMode displayMode;
targetWindow->GetDisplayMode (&displayMode);
return displayMode.Value ();
}
bool lime_window_get_enable_text_events (value window) {
Window* targetWindow = (Window*)val_data (window);
@@ -1636,6 +1646,17 @@ namespace lime {
}
value lime_window_set_display_mode (value window, value displayMode) {
Window* targetWindow = (Window*)val_data (window);
DisplayMode _displayMode (displayMode);
targetWindow->SetDisplayMode (&_displayMode);
targetWindow->GetDisplayMode (&_displayMode);
return _displayMode.Value ();
}
void lime_window_set_enable_text_events (value window, bool enabled) {
Window* targetWindow = (Window*)val_data (window);
@@ -1861,6 +1882,7 @@ namespace lime {
DEFINE_PRIME2v (lime_window_event_manager_register);
DEFINE_PRIME1v (lime_window_focus);
DEFINE_PRIME1 (lime_window_get_display);
DEFINE_PRIME1 (lime_window_get_display_mode);
DEFINE_PRIME1 (lime_window_get_enable_text_events);
DEFINE_PRIME1 (lime_window_get_height);
DEFINE_PRIME1 (lime_window_get_id);
@@ -1870,6 +1892,7 @@ namespace lime {
DEFINE_PRIME3v (lime_window_move);
DEFINE_PRIME3v (lime_window_resize);
DEFINE_PRIME2 (lime_window_set_borderless);
DEFINE_PRIME2 (lime_window_set_display_mode);
DEFINE_PRIME2v (lime_window_set_enable_text_events);
DEFINE_PRIME2 (lime_window_set_fullscreen);
DEFINE_PRIME2v (lime_window_set_icon);

View File

@@ -1,6 +1,7 @@
#include <graphics/PixelFormat.h>
#include <math/Rectangle.h>
#include <system/Clipboard.h>
#include <system/DisplayMode.h>
#include <system/JNI.h>
#include <system/System.h>
@@ -301,51 +302,69 @@ namespace lime {
#endif
alloc_field (display, id_dpi, alloc_float (dpi));
SDL_DisplayMode currentDisplayMode = { SDL_PIXELFORMAT_UNKNOWN, 0, 0, 0, 0 };
SDL_DisplayMode displayMode = { SDL_PIXELFORMAT_UNKNOWN, 0, 0, 0, 0 };
DisplayMode mode;
SDL_GetCurrentDisplayMode (id, &currentDisplayMode);
SDL_GetDesktopDisplayMode (id, &displayMode);
mode.height = displayMode.h;
switch (displayMode.format) {
case SDL_PIXELFORMAT_ARGB8888:
mode.pixelFormat = ARGB32;
break;
case SDL_PIXELFORMAT_BGRA8888:
case SDL_PIXELFORMAT_BGRX8888:
mode.pixelFormat = BGRA32;
break;
default:
mode.pixelFormat = RGBA32;
}
mode.refreshRate = displayMode.refresh_rate;
mode.width = displayMode.w;
alloc_field (display, id_currentMode, mode.Value ());
int numDisplayModes = SDL_GetNumDisplayModes (id);
value supportedModes = alloc_array (numDisplayModes);
value mode;
for (int i = 0; i < numDisplayModes; i++) {
SDL_GetDisplayMode (id, i, &displayMode);
if (displayMode.format == currentDisplayMode.format && displayMode.w == currentDisplayMode.w && displayMode.h == currentDisplayMode.h && displayMode.refresh_rate == currentDisplayMode.refresh_rate) {
alloc_field (display, id_currentMode, alloc_int (i));
}
mode = alloc_empty_object ();
alloc_field (mode, id_height, alloc_int (displayMode.h));
mode.height = displayMode.h;
switch (displayMode.format) {
case SDL_PIXELFORMAT_ARGB8888:
alloc_field (mode, id_pixelFormat, alloc_int (ARGB32));
mode.pixelFormat = ARGB32;
break;
case SDL_PIXELFORMAT_BGRA8888:
case SDL_PIXELFORMAT_BGRX8888:
alloc_field (mode, id_pixelFormat, alloc_int (BGRA32));
mode.pixelFormat = BGRA32;
break;
default:
alloc_field (mode, id_pixelFormat, alloc_int (RGBA32));
mode.pixelFormat = RGBA32;
}
alloc_field (mode, id_refreshRate, alloc_int (displayMode.refresh_rate));
alloc_field (mode, id_width, alloc_int (displayMode.w));
mode.refreshRate = displayMode.refresh_rate;
mode.width = displayMode.w;
val_array_set_i (supportedModes, i, mode);
val_array_set_i (supportedModes, i, mode.Value ());
}

View File

@@ -11,6 +11,9 @@
namespace lime {
static bool displayModeSet = false;
SDLWindow::SDLWindow (Application* application, int width, int height, int flags, const char* title) {
currentApplication = application;
@@ -196,6 +199,38 @@ namespace lime {
}
void SDLWindow::GetDisplayMode (DisplayMode* displayMode) {
SDL_DisplayMode mode;
SDL_GetWindowDisplayMode (sdlWindow, &mode);
displayMode->width = mode.w;
displayMode->height = mode.h;
switch (mode.format) {
case SDL_PIXELFORMAT_ARGB8888:
displayMode->pixelFormat = ARGB32;
break;
case SDL_PIXELFORMAT_BGRA8888:
case SDL_PIXELFORMAT_BGRX8888:
displayMode->pixelFormat = BGRA32;
break;
default:
displayMode->pixelFormat = RGBA32;
}
displayMode->refreshRate = mode.refresh_rate;
}
bool SDLWindow::GetEnableTextEvents () {
return SDL_IsTextInputActive ();
@@ -289,6 +324,45 @@ namespace lime {
}
void SDLWindow::SetDisplayMode (DisplayMode* displayMode) {
Uint32 pixelFormat = 0;
switch (displayMode->pixelFormat) {
case ARGB32:
pixelFormat = SDL_PIXELFORMAT_ARGB8888;
break;
case BGRA32:
pixelFormat = SDL_PIXELFORMAT_BGRA8888;
break;
default:
pixelFormat = SDL_PIXELFORMAT_RGBA8888;
}
SDL_DisplayMode mode = { pixelFormat, displayMode->width, displayMode->height, displayMode->refreshRate, 0 };
if (SDL_SetWindowDisplayMode (sdlWindow, &mode) == 0) {
displayModeSet = true;
if (SDL_GetWindowFlags (sdlWindow) & SDL_WINDOW_FULLSCREEN_DESKTOP) {
SDL_SetWindowFullscreen (sdlWindow, SDL_WINDOW_FULLSCREEN);
}
}
}
void SDLWindow::SetEnableTextEvents (bool enabled) {
if (enabled) {
@@ -308,7 +382,15 @@ namespace lime {
if (fullscreen) {
SDL_SetWindowFullscreen (sdlWindow, SDL_WINDOW_FULLSCREEN_DESKTOP);
if (displayModeSet) {
SDL_SetWindowFullscreen (sdlWindow, SDL_WINDOW_FULLSCREEN);
} else {
SDL_SetWindowFullscreen (sdlWindow, SDL_WINDOW_FULLSCREEN_DESKTOP);
}
} else {

View File

@@ -21,6 +21,7 @@ namespace lime {
virtual void Close ();
virtual void Focus ();
virtual int GetDisplay ();
virtual void GetDisplayMode (DisplayMode* displayMode);
virtual bool GetEnableTextEvents ();
virtual int GetHeight ();
virtual uint32_t GetID ();
@@ -30,6 +31,7 @@ namespace lime {
virtual void Move (int x, int y);
virtual void Resize (int width, int height);
virtual bool SetBorderless (bool borderless);
virtual void SetDisplayMode (DisplayMode* displayMode);
virtual void SetEnableTextEvents (bool enabled);
virtual bool SetFullscreen (bool fullscreen);
virtual void SetIcon (ImageBuffer *imageBuffer);

View File

@@ -0,0 +1,66 @@
#include <system/DisplayMode.h>
namespace lime {
static int id_height;
static int id_pixelFormat;
static int id_refreshRate;
static int id_width;
static bool init = false;
DisplayMode::DisplayMode () {
width = 0;
height = 0;
pixelFormat = RGBA32;
refreshRate = 0;
}
DisplayMode::DisplayMode (value displayMode) {
width = val_int (val_field (displayMode, id_width));
height = val_int (val_field (displayMode, id_height));
pixelFormat = (PixelFormat)val_int (val_field (displayMode, id_pixelFormat));
refreshRate = val_int (val_field (displayMode, id_refreshRate));
}
DisplayMode::DisplayMode (int _width, int _height, PixelFormat _pixelFormat, int _refreshRate) {
width = _width;
height = _height;
pixelFormat = _pixelFormat;
refreshRate = _refreshRate;
}
value DisplayMode::Value () {
if (!init) {
id_height = val_id ("height");
id_pixelFormat = val_id ("pixelFormat");
id_refreshRate = val_id ("refreshRate");
id_width = val_id ("width");
init = true;
}
value displayMode = alloc_empty_object ();
alloc_field (displayMode, id_height, alloc_int (height));
alloc_field (displayMode, id_pixelFormat, alloc_int (pixelFormat));
alloc_field (displayMode, id_refreshRate, alloc_int (refreshRate));
alloc_field (displayMode, id_width, alloc_int (width));
return displayMode;
}
}