reordered windows to match linux, trimming down the fullscreen code

This commit is contained in:
Allen Webster 2017-07-18 18:09:16 -04:00
parent 5836647d71
commit b52c82f1ae
9 changed files with 136 additions and 171 deletions

View File

@ -72,7 +72,7 @@ struct Application_Links;
#define DIRECTORY_CD_SIG(n) bool32 n(Application_Links *app, char *dir, int32_t *len, int32_t capacity, char *rel_path, int32_t rel_len)
#define GET_4ED_PATH_SIG(n) int32_t n(Application_Links *app, char *out, int32_t capacity)
#define SHOW_MOUSE_CURSOR_SIG(n) void n(Application_Links *app, Mouse_Cursor_Show_Type show)
#define TOGGLE_FULLSCREEN_SIG(n) void n(Application_Links *app)
#define SET_FULLSCREEN_SIG(n) bool32 n(Application_Links *app, bool32 full_screen)
#define IS_FULLSCREEN_SIG(n) bool32 n(Application_Links *app)
#define SEND_EXIT_SIGNAL_SIG(n) void n(Application_Links *app)
typedef GLOBAL_SET_SETTING_SIG(Global_Set_Setting_Function);
@ -148,7 +148,7 @@ typedef FILE_EXISTS_SIG(File_Exists_Function);
typedef DIRECTORY_CD_SIG(Directory_CD_Function);
typedef GET_4ED_PATH_SIG(Get_4ed_Path_Function);
typedef SHOW_MOUSE_CURSOR_SIG(Show_Mouse_Cursor_Function);
typedef TOGGLE_FULLSCREEN_SIG(Toggle_Fullscreen_Function);
typedef SET_FULLSCREEN_SIG(Set_Fullscreen_Function);
typedef IS_FULLSCREEN_SIG(Is_Fullscreen_Function);
typedef SEND_EXIT_SIGNAL_SIG(Send_Exit_Signal_Function);
struct Application_Links{
@ -226,7 +226,7 @@ File_Exists_Function *file_exists;
Directory_CD_Function *directory_cd;
Get_4ed_Path_Function *get_4ed_path;
Show_Mouse_Cursor_Function *show_mouse_cursor;
Toggle_Fullscreen_Function *toggle_fullscreen;
Set_Fullscreen_Function *set_fullscreen;
Is_Fullscreen_Function *is_fullscreen;
Send_Exit_Signal_Function *send_exit_signal;
#else
@ -303,7 +303,7 @@ File_Exists_Function *file_exists_;
Directory_CD_Function *directory_cd_;
Get_4ed_Path_Function *get_4ed_path_;
Show_Mouse_Cursor_Function *show_mouse_cursor_;
Toggle_Fullscreen_Function *toggle_fullscreen_;
Set_Fullscreen_Function *set_fullscreen_;
Is_Fullscreen_Function *is_fullscreen_;
Send_Exit_Signal_Function *send_exit_signal_;
#endif
@ -388,7 +388,7 @@ app_links->file_exists_ = File_Exists;\
app_links->directory_cd_ = Directory_CD;\
app_links->get_4ed_path_ = Get_4ed_Path;\
app_links->show_mouse_cursor_ = Show_Mouse_Cursor;\
app_links->toggle_fullscreen_ = Toggle_Fullscreen;\
app_links->set_fullscreen_ = Set_Fullscreen;\
app_links->is_fullscreen_ = Is_Fullscreen;\
app_links->send_exit_signal_ = Send_Exit_Signal;} while(false)
#if defined(ALLOW_DEP_4CODER)
@ -465,7 +465,7 @@ static inline bool32 file_exists(Application_Links *app, char *filename, int32_t
static inline bool32 directory_cd(Application_Links *app, char *dir, int32_t *len, int32_t capacity, char *rel_path, int32_t rel_len){return(app->directory_cd(app, dir, len, capacity, rel_path, rel_len));}
static inline int32_t get_4ed_path(Application_Links *app, char *out, int32_t capacity){return(app->get_4ed_path(app, out, capacity));}
static inline void show_mouse_cursor(Application_Links *app, Mouse_Cursor_Show_Type show){(app->show_mouse_cursor(app, show));}
static inline void toggle_fullscreen(Application_Links *app){(app->toggle_fullscreen(app));}
static inline bool32 set_fullscreen(Application_Links *app, bool32 full_screen){return(app->set_fullscreen(app, full_screen));}
static inline bool32 is_fullscreen(Application_Links *app){return(app->is_fullscreen(app));}
static inline void send_exit_signal(Application_Links *app){(app->send_exit_signal(app));}
#else
@ -542,7 +542,7 @@ static inline bool32 file_exists(Application_Links *app, char *filename, int32_t
static inline bool32 directory_cd(Application_Links *app, char *dir, int32_t *len, int32_t capacity, char *rel_path, int32_t rel_len){return(app->directory_cd_(app, dir, len, capacity, rel_path, rel_len));}
static inline int32_t get_4ed_path(Application_Links *app, char *out, int32_t capacity){return(app->get_4ed_path_(app, out, capacity));}
static inline void show_mouse_cursor(Application_Links *app, Mouse_Cursor_Show_Type show){(app->show_mouse_cursor_(app, show));}
static inline void toggle_fullscreen(Application_Links *app){(app->toggle_fullscreen_(app));}
static inline bool32 set_fullscreen(Application_Links *app, bool32 full_screen){return(app->set_fullscreen_(app, full_screen));}
static inline bool32 is_fullscreen(Application_Links *app){return(app->is_fullscreen_(app));}
static inline void send_exit_signal(Application_Links *app){(app->send_exit_signal_(app));}
#endif

View File

@ -225,6 +225,10 @@ CUSTOM_COMMAND_SIG(toggle_mouse){
set_mouse_suppression(app, !suppressing_mouse);
}
CUSTOM_COMMAND_SIG(toggle_fullscreen){
set_fullscreen(app, !is_fullscreen(app));
}
//
// Projects

View File

@ -2538,22 +2538,25 @@ DOC_SEE(Mouse_Cursor_Show_Type)
system->show_mouse_cursor(show);
}
API_EXPORT void
Toggle_Fullscreen(Application_Links *app)
API_EXPORT bool32
Set_Fullscreen(Application_Links *app, bool32 full_screen)
/*
DOC(This call tells 4coder to switch into or out of full screen mode.
DOC_PARAM(full_screen, The new value of the global full_screen setting.)
DOC(This call tells 4coder to set the full_screen mode.
The changes of full screen mode do not take effect until the end of the current frame.
On Windows this call will not work unless 4coder was started in "stream mode".
Stream mode can be enabled with -S or -F flags on the command line to 4ed.)
*/{
Command_Data *cmd = (Command_Data*)app->cmd_context;
System_Functions *system = cmd->system;
if (!system->toggle_fullscreen()){
bool32 success = system->set_fullscreen(full_screen);
if (!success){
char msg[] =
"ERROR: Failed to go fullscreen.\n"
"You can try using 'stream mode' by launching with the -S flag.\n";
print_message(app, literal(msg));
}
return(success);
}
API_EXPORT bool32

View File

@ -202,8 +202,8 @@ typedef Sys_Get_4ed_Path_Sig(System_Get_4ed_Path);
#define Sys_Show_Mouse_Cursor_Sig(name) void name(i32 show)
typedef Sys_Show_Mouse_Cursor_Sig(System_Show_Mouse_Cursor);
#define Sys_Toggle_Fullscreen_Sig(name) b32 name()
typedef Sys_Toggle_Fullscreen_Sig(System_Toggle_Fullscreen);
#define Sys_Set_Fullscreen_Sig(name) b32 name(b32 full_screen)
typedef Sys_Set_Fullscreen_Sig(System_Set_Fullscreen);
#define Sys_Is_Fullscreen_Sig(name) bool32 name()
typedef Sys_Is_Fullscreen_Sig(System_Is_Fullscreen);
@ -267,7 +267,7 @@ struct System_Functions{
System_Directory_CD *directory_cd;
System_Get_4ed_Path *get_4ed_path;
System_Show_Mouse_Cursor *show_mouse_cursor;
System_Toggle_Fullscreen *toggle_fullscreen;
System_Set_Fullscreen *set_fullscreen;
System_Is_Fullscreen *is_fullscreen;
System_Send_Exit_Signal *send_exit_signal;

View File

@ -53,7 +53,7 @@ link_system_code(System_Functions *system){
SYSLINK(file_exists);
SYSLINK(directory_cd);
SYSLINK(get_4ed_path);
SYSLINK(toggle_fullscreen);
SYSLINK(set_fullscreen);
SYSLINK(is_fullscreen);
SYSLINK(show_mouse_cursor);
SYSLINK(send_exit_signal);

View File

@ -162,6 +162,8 @@ struct Linux_Vars{
u64 last_step;
b32 full_screen;
b32 do_toggle;
b32 keep_running;
Application_Mouse_Cursor cursor;
@ -194,24 +196,14 @@ global Plat_Settings plat_settings;
#define SLASH '/'
internal Plat_Handle
handle_sem(sem_t *sem){
return(*(Plat_Handle*)&sem);
}
internal sem_t*
handle_sem(Plat_Handle h){
return(*(sem_t**)&h);
}
internal Plat_Handle
handle_fd(int fd){
return(*(Plat_Handle*)&fd);
}
internal int
handle_fd(Plat_Handle h){
return(*(int*)&h);
handle_sem(sem_t *sem){
return(*(Plat_Handle*)&sem);
}
////////////////////////////////
@ -244,8 +236,12 @@ system_schedule_step(){
////////////////////////////////
#include "4ed_work_queues.cpp"
////////////////////////////////
internal void
LinuxSetWMState(Display* d, Window w, Atom one, Atom two, int mode){
linux_set_wm_state(Display* d, Window w, Atom one, Atom two, int mode){
//NOTE(inso): this will only work after it is mapped
enum { STATE_REMOVE, STATE_ADD, STATE_TOGGLE };
@ -264,42 +260,40 @@ LinuxSetWMState(Display* d, Window w, Atom one, Atom two, int mode){
XSendEvent(d, RootWindow(d, 0), 0, SubstructureNotifyMask | SubstructureRedirectMask, &e);
}
////////////////////////////////
internal void
linux_maximize_window(b32 maximize){
linux_set_wm_state(linuxvars.XDisplay, linuxvars.XWindow, linuxvars.atom__NET_WM_STATE_MAXIMIZED_HORZ, linuxvars.atom__NET_WM_STATE_MAXIMIZED_VERT, maximize?1:0);
}
internal void
linux_toggle_fullscreen(){
linuxvars.full_screen = !linuxvars.full_screen;
linux_set_wm_state(linuxvars.XDisplay, linuxvars.XWindow, linuxvars.atom__NET_WM_STATE_FULLSCREEN, 0, linuxvars.full_screen?1:0);
}
internal
Sys_Show_Mouse_Cursor_Sig(system_show_mouse_cursor){
linuxvars.hide_cursor = !show;
XDefineCursor(linuxvars.XDisplay, linuxvars.XWindow, show ? None : linuxvars.hidden_cursor);
XDefineCursor(linuxvars.XDisplay, linuxvars.XWindow, show?None:linuxvars.hidden_cursor);
}
internal
Sys_Toggle_Fullscreen_Sig(system_toggle_fullscreen){
Sys_Set_Fullscreen_Sig(system_set_fullscreen){
b32 success = true;
LinuxSetWMState(linuxvars.XDisplay, linuxvars.XWindow, linuxvars.atom__NET_WM_STATE_FULLSCREEN, 0, 2);
linuxvars.do_toggle = (linuxvars.full_screen != full_screen);
return(success);
}
internal
Sys_Is_Fullscreen_Sig(system_is_fullscreen){
b32 result = false;
Atom type, *prop;
unsigned long nitems, pad;
int fmt;
int ret = XGetWindowProperty(linuxvars.XDisplay, linuxvars.XWindow, linuxvars.atom__NET_WM_STATE, 0, 32, False, XA_ATOM, &type, &fmt, &nitems, &pad, (unsigned char**)&prop);
if (ret == Success && prop){
result = (*prop == linuxvars.atom__NET_WM_STATE_FULLSCREEN);
XFree((unsigned char*)prop);
}
return result;
b32 result = (linuxvars.full_screen != linuxvars.do_toggle);
return(result);
}
// HACK(allen): Why does this work differently from the win32 version!?
internal
Sys_Send_Exit_Signal_Sig(system_send_exit_signal){
linuxvars.keep_running = 0;
linuxvars.keep_running = false;
}
//
@ -515,8 +509,6 @@ Sys_CLI_End_Update_Sig(system_cli_end_update){
return(close_me);
}
#include "4ed_work_queues.cpp"
//
// Linux rendering/font system functions
//
@ -1081,12 +1073,6 @@ LinuxStringDup(String* str, void* data, size_t size){
// X11 utility funcs
//
internal void
LinuxMaximizeWindow(Display* d, Window w, b32 maximize)
{
LinuxSetWMState(d, w, linuxvars.atom__NET_WM_STATE_MAXIMIZED_HORZ, linuxvars.atom__NET_WM_STATE_MAXIMIZED_VERT, maximize != 0);
}
#include "linux_icon.h"
internal void
LinuxSetIcon(Display* d, Window w)
@ -1503,7 +1489,7 @@ LinuxX11WindowInit(int argc, char** argv, int* window_width, int* window_height)
LinuxSetIcon(linuxvars.XDisplay, linuxvars.XWindow);
//NOTE(inso): make the window visible
// NOTE(inso): make the window visible
XMapWindow(linuxvars.XDisplay, linuxvars.XWindow);
b32 IsLegacy = false;
@ -1517,7 +1503,7 @@ LinuxX11WindowInit(int argc, char** argv, int* window_width, int* window_height)
}
if (plat_settings.maximize_window){
LinuxMaximizeWindow(linuxvars.XDisplay, linuxvars.XWindow, 1);
linux_maximize_window(true);
}
else if (plat_settings.fullscreen_window){
system_toggle_fullscreen();
@ -1539,7 +1525,7 @@ LinuxX11WindowInit(int argc, char** argv, int* window_width, int* window_height)
XSetWMProtocols(linuxvars.XDisplay, linuxvars.XWindow, wm_protos, 2);
return true;
return(true);
}
internal void
@ -1917,8 +1903,6 @@ main(int argc, char **argv){
return(1);
}
unixvars.use_log = plat_settings.use_log;
sysshared_filter_real_files(files, file_count);
//
@ -2230,7 +2214,12 @@ main(int argc, char **argv){
if (result.perform_kill){
break;
} else if (!keep_running && !linuxvars.keep_running){
linuxvars.keep_running = 1;
linuxvars.keep_running = true;
}
if (linuxvars.do_toggle){
linux_toggle_fullscreen();
linuxvars.do_toggle = false;
}
if (result.animating){

View File

@ -10,11 +10,9 @@
// TOP
struct Unix_Vars{
u32 use_log;
b32 did_first_log;
};
static Unix_Vars unixvars;
global Unix_Vars unixvars;
//
// 4ed Path
@ -41,7 +39,7 @@ Sys_Get_4ed_Path_Sig(system_get_4ed_path){
internal
Sys_Log_Sig(system_log){
if (unixvars.use_log == LogTo_LogFile){
if (plat_settings.use_log == LogTo_LogFile){
char file_path_space[1024];
String file_path = make_fixed_width_string(file_path_space);
file_path.size = system_get_4ed_path(file_path.str, file_path.memory_size);
@ -68,7 +66,7 @@ Sys_Log_Sig(system_log){
close(fd);
}
}
else if (unixvars.use_log == LogTo_Stdout){
else if (plat_settings.use_log == LogTo_Stdout){
fwrite(message, 1, length, stdout);
}
}

View File

@ -150,7 +150,6 @@ struct Win32_Vars{
i32 running_cli;
u32 log_position;
};
////////////////////////////////
@ -192,12 +191,74 @@ system_schedule_step(){
////////////////////////////////
//
// Threads
//
#include "4ed_work_queues.cpp"
////////////////////////////////
// HACK(allen): Get this shit working more properly (look at pens)
internal void
win32_toggle_fullscreen(){
HWND Window = win32vars.window_handle;
LONG_PTR Style = GetWindowLongPtr(Window, GWL_STYLE);
if (Style & WS_OVERLAPPEDWINDOW){
MONITORINFO MonitorInfo = {sizeof(MONITORINFO)};
if(GetWindowPlacement(Window, &win32vars.GlobalWindowPosition) && GetMonitorInfo(MonitorFromWindow(Window, MONITOR_DEFAULTTOPRIMARY), &MonitorInfo))
{
SetWindowLongPtr(Window, GWL_STYLE, Style & ~WS_OVERLAPPEDWINDOW);
SetWindowPos(Window, HWND_TOP,
MonitorInfo.rcMonitor.left, MonitorInfo.rcMonitor.top,
MonitorInfo.rcMonitor.right - MonitorInfo.rcMonitor.left,
MonitorInfo.rcMonitor.bottom - MonitorInfo.rcMonitor.top,
SWP_NOOWNERZORDER | SWP_FRAMECHANGED);
win32vars.full_screen = true;
}
}
else{
SetWindowLongPtr(Window, GWL_STYLE, Style | WS_OVERLAPPEDWINDOW);
SetWindowPlacement(Window, &win32vars.GlobalWindowPosition);
SetWindowPos(Window, 0, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_NOOWNERZORDER | SWP_FRAMECHANGED);
win32vars.full_screen = false;
}
}
// TODO(allen): add a "shown but auto-hides on timer" setting here.
internal
Sys_Show_Mouse_Cursor_Sig(system_show_mouse_cursor){
switch (show){
case MouseCursorShow_Never: ShowCursor(false); break;
case MouseCursorShow_Always: ShowCursor(true); break;
// TODO(allen): MouseCursor_HideWhenStill
}
}
internal
Sys_Set_Fullscreen_Sig(system_set_fullscreen){
b32 success = false;
// HACK(allen): Fix this shit.
// NOTE(allen): On windows we must be in stream mode to go fullscreen.
if (plat_settings.stream_mode){
// NOTE(allen): If the new value of full_screen does not match the current value,
// set toggle to true.
win32vars.do_toggle = (win32vars.full_screen != full_screen);
success = true;
}
return(success);
}
internal
Sys_Is_Fullscreen_Sig(system_is_fullscreen){
// NOTE(allen): Report the fullscreen status as it would be set at the beginning of the next frame.
// That is, take into account all fullscreen toggle requests that have come in already this frame.
// Read: "full_screen XOR do_toggle"
b32 result = (win32vars.full_screen != win32vars.do_toggle);
return(result);
}
internal
Sys_Send_Exit_Signal_Sig(system_send_exit_signal){
win32vars.send_exit_signal = true;
}
//
// Coroutines
//
@ -292,43 +353,6 @@ Sys_Yield_Coroutine_Sig(system_yield_coroutine){
SwitchToFiber(coroutine->yield_handle);
}
//
// Files
//
/*
NOTE(casey): This follows Raymond Chen's prescription
for fullscreen toggling, see:
http://blogs.msdn.com/b/oldnewthing/archive/2010/04/12/9994016.aspx
*/
internal void
Win32ToggleFullscreen(void){
HWND Window = win32vars.window_handle;
LONG_PTR Style = GetWindowLongPtr(Window, GWL_STYLE);
if (Style & WS_OVERLAPPEDWINDOW){
MONITORINFO MonitorInfo = {sizeof(MONITORINFO)};
if(GetWindowPlacement(Window, &win32vars.GlobalWindowPosition) && GetMonitorInfo(MonitorFromWindow(Window, MONITOR_DEFAULTTOPRIMARY), &MonitorInfo))
{
SetWindowLongPtr(Window, GWL_STYLE, Style & ~WS_OVERLAPPEDWINDOW);
SetWindowPos(Window, HWND_TOP,
MonitorInfo.rcMonitor.left, MonitorInfo.rcMonitor.top,
MonitorInfo.rcMonitor.right - MonitorInfo.rcMonitor.left,
MonitorInfo.rcMonitor.bottom - MonitorInfo.rcMonitor.top,
SWP_NOOWNERZORDER | SWP_FRAMECHANGED);
win32vars.full_screen = true;
}
}
else{
SetWindowLongPtr(Window, GWL_STYLE, Style | WS_OVERLAPPEDWINDOW);
SetWindowPlacement(Window, &win32vars.GlobalWindowPosition);
SetWindowPos(Window, 0, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_NOOWNERZORDER | SWP_FRAMECHANGED);
win32vars.full_screen = false;
}
}
//
// Clipboard
//
@ -537,59 +561,6 @@ Sys_CLI_End_Update_Sig(system_cli_end_update){
return(close_me);
}
//
// Appearence Settings
//
// TODO(allen): add a "shown but auto-hides on timer" setting here.
internal
Sys_Show_Mouse_Cursor_Sig(system_show_mouse_cursor){
switch (show){
case MouseCursorShow_Never:
ShowCursor(false);
break;
case MouseCursorShow_Always:
ShowCursor(true);
break;
// TODO(allen): MouseCursor_HideWhenStill
}
}
internal
Sys_Toggle_Fullscreen_Sig(system_toggle_fullscreen){
/* NOTE(allen): Don't actually change window size now!
Tell the platform layer to do the toggle (or to cancel the toggle)
later when the app.step function isn't running. If the size changes
mid step, it messes up the rendering rules and stuff. */
b32 success = false;
// NOTE(allen): On windows we must be in stream mode to go fullscreen.
if (plat_settings.stream_mode){
win32vars.do_toggle = !win32vars.do_toggle;
success = true;
}
return(success);
}
internal
Sys_Is_Fullscreen_Sig(system_is_fullscreen){
/* NOTE(allen): This is a fancy way to say 'full_screen XOR do_toggle'
This way this function can always report the state the fullscreen
will have when the next frame runs, given the number of toggles
that have occurred this frame and the original value. */
bool32 result = (win32vars.full_screen + win32vars.do_toggle) & 1;
return(result);
}
internal
Sys_Send_Exit_Signal_Sig(system_send_exit_signal){
win32vars.send_exit_signal = 1;
}
//
// Linkage to Custom and Application
//
@ -1380,12 +1351,12 @@ WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdS
system_memory_free(current_directory.str, 0);
b32 keep_playing = true;
b32 keep_running = true;
win32vars.first = true;
timeBeginPeriod(1);
if (plat_settings.fullscreen_window){
Win32ToggleFullscreen();
win32_toggle_fullscreen();
}
SetForegroundWindow(win32vars.window_handle);
@ -1396,7 +1367,7 @@ WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdS
u64 timer_start = Win32HighResolutionTime();
system_acquire_lock(FRAME_LOCK);
MSG msg;
for (;keep_playing;){
for (;keep_running;){
// TODO(allen): Find a good way to wait on a pipe
// without interfering with the reading process
// Looks like we can ReadFile with a size of zero
@ -1425,7 +1396,7 @@ WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdS
if (get_more_messages){
if (msg.message == WM_QUIT){
keep_playing = 0;
keep_running = false;
}else{
b32 treat_normally = true;
if (msg.message == WM_KEYDOWN || msg.message == WM_SYSKEYDOWN){
@ -1573,19 +1544,19 @@ WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdS
result.perform_kill = 0;
if (win32vars.send_exit_signal){
result.trying_to_kill = 1;
win32vars.send_exit_signal = 0;
result.trying_to_kill = true;
win32vars.send_exit_signal = false;
}
win32vars.app.step(&sysfunc, &win32vars.target, &memory_vars, &input, &result, clparams);
if (result.perform_kill){
keep_playing = 0;
keep_running = false;
}
if (win32vars.do_toggle){
Win32ToggleFullscreen();
win32vars.do_toggle = 0;
win32_toggle_fullscreen();
win32vars.do_toggle = false;
}
Win32SetCursorFromUpdate(result.mouse_cursor_type);

View File

@ -46,7 +46,7 @@ Sys_Log_Sig(system_log){
do{
WriteFile(file, message + total_written, length - total_written, &written, 0);
total_written += written;
}while(total_written < length);
}while (total_written < length);
CloseHandle(file);
}
}