cleaned up the windows fullscreen BULLS

master
Allen Webster 2017-07-18 18:34:57 -04:00
parent b52c82f1ae
commit db78c80cda
12 changed files with 84 additions and 113 deletions

10
4ed.cpp
View File

@ -765,7 +765,6 @@ enum Command_Line_Action{
CLAct_WindowMaximize, CLAct_WindowMaximize,
CLAct_WindowPosition, CLAct_WindowPosition,
CLAct_WindowFullscreen, CLAct_WindowFullscreen,
CLAct_WindowStreamMode,
CLAct_FontSize, CLAct_FontSize,
CLAct_FontUseHinting, CLAct_FontUseHinting,
CLAct_LogStdout, CLAct_LogStdout,
@ -820,7 +819,6 @@ init_command_line_settings(App_Settings *settings, Plat_Settings *plat_settings,
case 'W': action = CLAct_WindowMaximize; break; case 'W': action = CLAct_WindowMaximize; break;
case 'p': action = CLAct_WindowPosition; break; case 'p': action = CLAct_WindowPosition; break;
case 'F': action = CLAct_WindowFullscreen; break; case 'F': action = CLAct_WindowFullscreen; break;
case 'S': action = CLAct_WindowStreamMode; break;
case 'f': action = CLAct_FontSize; break; case 'f': action = CLAct_FontSize; break;
case 'h': action = CLAct_FontUseHinting; --i; break; case 'h': action = CLAct_FontUseHinting; --i; break;
@ -903,14 +901,6 @@ init_command_line_settings(App_Settings *settings, Plat_Settings *plat_settings,
{ {
--i; --i;
plat_settings->fullscreen_window = true; plat_settings->fullscreen_window = true;
plat_settings->stream_mode = true;
action = CLAct_Nothing;
}break;
case CLAct_WindowStreamMode:
{
--i;
plat_settings->stream_mode = true;
action = CLAct_Nothing; action = CLAct_Nothing;
}break; }break;

1
4ed.h
View File

@ -63,7 +63,6 @@ struct Plat_Settings{
char *custom_dll; char *custom_dll;
b8 custom_dll_is_strict; b8 custom_dll_is_strict;
b8 fullscreen_window; b8 fullscreen_window;
b8 stream_mode;
u8 use_log; u8 use_log;

View File

@ -2542,19 +2542,13 @@ API_EXPORT bool32
Set_Fullscreen(Application_Links *app, bool32 full_screen) Set_Fullscreen(Application_Links *app, bool32 full_screen)
/* /*
DOC_PARAM(full_screen, The new value of the global full_screen setting.) DOC_PARAM(full_screen, The new value of the global full_screen setting.)
DOC(This call tells 4coder to set the full_screen mode. DOC(This call tells 4coder to set the full_screen mode. The change to full screen mode does not take effect until the end of the current frame. But is_fullscreen does report the new state.)
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; Command_Data *cmd = (Command_Data*)app->cmd_context;
System_Functions *system = cmd->system; System_Functions *system = cmd->system;
bool32 success = system->set_fullscreen(full_screen); bool32 success = system->set_fullscreen(full_screen);
if (!success){ if (!success){
char msg[] = print_message(app, literal("ERROR: Failed to go fullscreen.\n"));
"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); return(success);
} }

View File

@ -16,10 +16,10 @@
#include "4ed_font_data.h" #include "4ed_font_data.h"
#include "4coder_helper/4coder_seek_types.h" #include "4coder_helper/4coder_seek_types.h"
typedef struct Cursor_With_Index{ struct Cursor_With_Index{
i32 pos; i32 pos;
i32 index; i32 index;
} Cursor_With_Index; };
inline void inline void
write_cursor_with_index(Cursor_With_Index *positions, i32 *count, i32 pos){ write_cursor_with_index(Cursor_With_Index *positions, i32 *count, i32 pos){
@ -279,7 +279,7 @@ eol_in_place_convert_out(char *data, i32 size, i32 max, i32 *size_out){
// Implementation of the gap buffer // Implementation of the gap buffer
// //
typedef struct Gap_Buffer{ struct Gap_Buffer{
char *data; char *data;
i32 size1; i32 size1;
i32 gap_size; i32 gap_size;
@ -289,7 +289,7 @@ typedef struct Gap_Buffer{
i32 *line_starts; i32 *line_starts;
i32 line_count; i32 line_count;
i32 line_max; i32 line_max;
} Gap_Buffer; };
inline i32 inline i32
buffer_good(Gap_Buffer *buffer){ buffer_good(Gap_Buffer *buffer){
@ -303,11 +303,11 @@ buffer_size(Gap_Buffer *buffer){
return(size); return(size);
} }
typedef struct Gap_Buffer_Init{ struct Gap_Buffer_Init{
Gap_Buffer *buffer; Gap_Buffer *buffer;
char *data; char *data;
i32 size; i32 size;
} Gap_Buffer_Init; };
internal Gap_Buffer_Init internal Gap_Buffer_Init
buffer_begin_init(Gap_Buffer *buffer, char *data, i32 size){ buffer_begin_init(Gap_Buffer *buffer, char *data, i32 size){
@ -367,7 +367,7 @@ buffer_end_init(Gap_Buffer_Init *init, void *scratch, i32 scratch_size){
return(result); return(result);
} }
typedef struct Gap_Buffer_Stream{ struct Gap_Buffer_Stream{
Gap_Buffer *buffer; Gap_Buffer *buffer;
char *data; char *data;
i32 end; i32 end;
@ -376,8 +376,8 @@ typedef struct Gap_Buffer_Stream{
b32 use_termination_character; b32 use_termination_character;
char terminator; char terminator;
} Gap_Buffer_Stream; };
static Gap_Buffer_Stream null_buffer_stream = {0}; global Gap_Buffer_Stream null_buffer_stream = {0};
internal b32 internal b32
buffer_stringify_loop(Gap_Buffer_Stream *stream, Gap_Buffer *buffer, i32 start, i32 end){ buffer_stringify_loop(Gap_Buffer_Stream *stream, Gap_Buffer *buffer, i32 start, i32 end){
@ -495,10 +495,10 @@ buffer_replace_range(Gap_Buffer *buffer, i32 start, i32 end, char *str, i32 len,
return(result); return(result);
} }
typedef struct Buffer_Batch_State{ struct Buffer_Batch_State{
i32 i; i32 i;
i32 shift_total; i32 shift_total;
} Buffer_Batch_State; };
// TODO(allen): Now that we are just using Gap_Buffer we could afford to improve // TODO(allen): Now that we are just using Gap_Buffer we could afford to improve
// this for the Gap_Buffer's behavior. // this for the Gap_Buffer's behavior.
@ -611,11 +611,11 @@ buffer_count_newlines(Gap_Buffer *buffer, i32 start, i32 end){
return(count); return(count);
} }
typedef struct Buffer_Measure_Starts{ struct Buffer_Measure_Starts{
i32 i; i32 i;
i32 count; i32 count;
i32 start; i32 start;
} Buffer_Measure_Starts; };
// TODO(allen): Rewrite this with a duff routine // TODO(allen): Rewrite this with a duff routine
// Also make it so that the array goes one past the end // Also make it so that the array goes one past the end
@ -1683,11 +1683,11 @@ buffer_invert_edit(Gap_Buffer *buffer, Buffer_Edit edit, Buffer_Edit *inverse, c
buffer_invert_edit_shift(buffer, edit, inverse, strings, str_pos, max, 0); buffer_invert_edit_shift(buffer, edit, inverse, strings, str_pos, max, 0);
} }
typedef struct Buffer_Invert_Batch{ struct Buffer_Invert_Batch{
i32 i; i32 i;
i32 shift_amount; i32 shift_amount;
i32 len; i32 len;
} Buffer_Invert_Batch; };
internal i32 internal i32
buffer_invert_batch(Buffer_Invert_Batch *state, Gap_Buffer *buffer, Buffer_Edit *edits, i32 count, buffer_invert_batch(Buffer_Invert_Batch *state, Gap_Buffer *buffer, Buffer_Edit *edits, i32 count,
@ -1720,15 +1720,15 @@ enum Buffer_Render_Flag{
BRFlag_Ghost_Character = (1 << 1) BRFlag_Ghost_Character = (1 << 1)
}; };
typedef struct Buffer_Render_Item{ struct Buffer_Render_Item{
i32 index; i32 index;
u32 codepoint; u32 codepoint;
u32 flags; u32 flags;
f32 x0, y0; f32 x0, y0;
f32 x1, y1; f32 x1, y1;
} Buffer_Render_Item; };
typedef struct Render_Item_Write{ struct Render_Item_Write{
Buffer_Render_Item *item; Buffer_Render_Item *item;
f32 x, y; f32 x, y;
System_Functions *system; System_Functions *system;
@ -1736,7 +1736,7 @@ typedef struct Render_Item_Write{
i32 font_height; i32 font_height;
f32 x_min; f32 x_min;
f32 x_max; f32 x_max;
} Render_Item_Write; };
inline Render_Item_Write inline Render_Item_Write
write_render_item(Render_Item_Write write, i32 index, u32 codepoint, u32 flags){ write_render_item(Render_Item_Write write, i32 index, u32 codepoint, u32 flags){

View File

@ -16,9 +16,9 @@
# define FILE_TRACK_LINK static # define FILE_TRACK_LINK static
#endif #endif
typedef struct{ struct File_Track_System{
u8 opaque[128]; u8 opaque[128];
} File_Track_System; };
typedef i32 File_Track_Result; typedef i32 File_Track_Result;
enum{ enum{

View File

@ -9,34 +9,32 @@
// TOP // TOP
typedef struct{ struct File_Index{
u32 id[4]; u32 id[4];
} File_Index; };
typedef u32 rptr32; typedef u32 rptr32;
#define to_ptr(b,p) ((void*)((char*)b + p)) #define to_ptr(b,p) ((void*)((char*)b + p))
#define to_rptr32(b,p) ((rptr32)((char*)(p) - (char*)(b))) #define to_rptr32(b,p) ((rptr32)((char*)(p) - (char*)(b)))
typedef struct { struct File_Track_Entry{
File_Index hash; File_Index hash;
u32 opaque[4]; u32 opaque[4];
} File_Track_Entry; };
global_const File_Track_Entry null_file_track_entry = {0}; global_const File_Track_Entry null_file_track_entry = {0};
typedef struct { struct File_Track_Tables{
i32 size; i32 size;
u32 tracked_count; u32 tracked_count;
u32 max; u32 max;
rptr32 file_table; rptr32 file_table;
} File_Track_Tables; };
typedef struct DLL_Node {
struct DLL_Node *next;
struct DLL_Node *prev;
} DLL_Node;
struct DLL_Node {
DLL_Node *next;
DLL_Node *prev;
};
internal File_Index internal File_Index
zero_file_index(){ zero_file_index(){

View File

@ -90,22 +90,22 @@ internal void fm_end_temp(Temp temp);
internal i32 fm_get_current_directory(char *buffer, i32 max); internal i32 fm_get_current_directory(char *buffer, i32 max);
typedef struct Temp_Dir{ struct Temp_Dir{
char dir[512]; char dir[512];
} Temp_Dir; };
internal Temp_Dir fm_pushdir(char *dir); internal Temp_Dir fm_pushdir(char *dir);
internal void fm_popdir(Temp_Dir temp); internal void fm_popdir(Temp_Dir temp);
// Build Line // Build Line
#define BUILD_LINE_MAX 4096 #define BUILD_LINE_MAX 4096
typedef struct Build_Line{ struct Build_Line{
char build_optionsA[BUILD_LINE_MAX]; char build_optionsA[BUILD_LINE_MAX];
char build_optionsB[BUILD_LINE_MAX]; char build_optionsB[BUILD_LINE_MAX];
char *build_options; char *build_options;
char *build_options_prev; char *build_options_prev;
i32 build_max; i32 build_max;
} Build_Line; };
internal void fm_init_build_line(Build_Line *line); internal void fm_init_build_line(Build_Line *line);
internal void fm_finish_build_line(Build_Line *line); internal void fm_finish_build_line(Build_Line *line);

View File

@ -56,10 +56,10 @@ typedef int32_t bool32;
#include "../4cpp/4cpp_lexer_types.h" #include "../4cpp/4cpp_lexer_types.h"
#include "../4ed_mem_ansi.c" #include "../4ed_mem_ansi.c"
typedef struct Whitespace_FSM{ struct Whitespace_FSM{
unsigned char pp_state; unsigned char pp_state;
unsigned char white_done; unsigned char white_done;
} Whitespace_FSM; };
Whitespace_FSM Whitespace_FSM
whitespace_skip_fsm(Whitespace_FSM wfsm, char c){ whitespace_skip_fsm(Whitespace_FSM wfsm, char c){
@ -765,7 +765,7 @@ end_table(FILE *file){
fprintf(file, "};\n\n"); fprintf(file, "};\n\n");
} }
typedef struct FSM_Tables{ struct FSM_Tables{
u8_4tech *full_transition_table; u8_4tech *full_transition_table;
u8_4tech *marks; u8_4tech *marks;
u8_4tech *eq_class; u8_4tech *eq_class;
@ -775,7 +775,7 @@ typedef struct FSM_Tables{
u8_4tech eq_class_counter; u8_4tech eq_class_counter;
u16_4tech state_count; u16_4tech state_count;
} FSM_Tables; };
static void static void
allocate_full_tables(FSM_Tables *table, uint8_t state_count){ allocate_full_tables(FSM_Tables *table, uint8_t state_count){
@ -950,11 +950,11 @@ render_comment(FILE *file, char *comment){
fprintf(file, "/*\n%s*/\n", comment); fprintf(file, "/*\n%s*/\n", comment);
} }
typedef struct PP_Names{ struct PP_Names{
uint8_t pp_state; uint8_t pp_state;
char *name; char *name;
bool32 ignore_string_delims; bool32 ignore_string_delims;
} PP_Names; };
static PP_Names pp_names[] = { static PP_Names pp_names[] = {
{LSPP_default, "main_fsm", false}, {LSPP_default, "main_fsm", false},

View File

@ -817,11 +817,11 @@ GLXCanUseFBConfig(Display *XDisplay)
return(Result); return(Result);
} }
typedef struct glx_config_result{ struct glx_config_result{
b32 Found; b32 Found;
GLXFBConfig BestConfig; GLXFBConfig BestConfig;
XVisualInfo BestInfo; XVisualInfo BestInfo;
} glx_config_result; };
internal glx_config_result internal glx_config_result
ChooseGLXConfig(Display *XDisplay, int XScreenIndex) ChooseGLXConfig(Display *XDisplay, int XScreenIndex)

View File

@ -14,19 +14,19 @@
#include <libgen.h> // dirname #include <libgen.h> // dirname
typedef struct { struct Linux_File_Track_Vars{
void *tables; void *tables;
int inotify; int inotify;
pthread_mutex_t lock; pthread_mutex_t lock;
char *string_mem_begin; char *string_mem_begin;
char *string_mem_end; char *string_mem_end;
} Linux_File_Track_Vars; };
typedef struct { struct Linux_File_Track_Entry{
File_Index hash; File_Index hash;
char* dir; char* dir;
int ref_count; int ref_count;
} Linux_File_Track_Entry; };
#define to_vars(s) ((Linux_File_Track_Vars*)(s)) #define to_vars(s) ((Linux_File_Track_Vars*)(s))
#define to_tables(v) ((File_Track_Tables*)(v->tables)) #define to_tables(v) ((File_Track_Tables*)(v->tables))

View File

@ -127,7 +127,7 @@ struct Win32_Vars{
b32 full_screen; b32 full_screen;
b32 do_toggle; b32 do_toggle;
WINDOWPLACEMENT GlobalWindowPosition; WINDOWPLACEMENT bordered_win_pos;
b32 send_exit_signal; b32 send_exit_signal;
HCURSOR cursor_ibeam; HCURSOR cursor_ibeam;
@ -198,25 +198,27 @@ system_schedule_step(){
// HACK(allen): Get this shit working more properly (look at pens) // HACK(allen): Get this shit working more properly (look at pens)
internal void internal void
win32_toggle_fullscreen(){ win32_toggle_fullscreen(){
HWND Window = win32vars.window_handle; HWND win = win32vars.window_handle;
LONG_PTR Style = GetWindowLongPtr(Window, GWL_STYLE); DWORD style = GetWindowLongW(win, GWL_STYLE);
if (Style & WS_OVERLAPPEDWINDOW){ b32 is_full = ((style & WS_OVERLAPPEDWINDOW) != 0);
MONITORINFO MonitorInfo = {sizeof(MONITORINFO)}; if (is_full){
if(GetWindowPlacement(Window, &win32vars.GlobalWindowPosition) && GetMonitorInfo(MonitorFromWindow(Window, MONITOR_DEFAULTTOPRIMARY), &MonitorInfo)) MONITORINFO info = {sizeof(MONITORINFO)};
{ if (GetWindowPlacement(win, &win32vars.bordered_win_pos) && GetMonitorInfo(MonitorFromWindow(win, MONITOR_DEFAULTTOPRIMARY), &info)){
SetWindowLongPtr(Window, GWL_STYLE, Style & ~WS_OVERLAPPEDWINDOW); SetWindowLongW(win, GWL_STYLE, style & ~WS_OVERLAPPEDWINDOW);
SetWindowPos(Window, HWND_TOP,
MonitorInfo.rcMonitor.left, MonitorInfo.rcMonitor.top, i32 x = info.rcMonitor.left;
MonitorInfo.rcMonitor.right - MonitorInfo.rcMonitor.left, i32 y = info.rcMonitor.top;
MonitorInfo.rcMonitor.bottom - MonitorInfo.rcMonitor.top, i32 w = info.rcMonitor.right - info.rcMonitor.left;
SWP_NOOWNERZORDER | SWP_FRAMECHANGED); i32 h = info.rcMonitor.bottom - info.rcMonitor.top;
SetWindowPos(win, HWND_TOP, x, y, w, h, SWP_NOOWNERZORDER | SWP_FRAMECHANGED | SWP_SHOWWINDOW);
win32vars.full_screen = true; win32vars.full_screen = true;
} }
} }
else{ else{
SetWindowLongPtr(Window, GWL_STYLE, Style | WS_OVERLAPPEDWINDOW); SetWindowLongW(win, GWL_STYLE, style | WS_OVERLAPPEDWINDOW);
SetWindowPlacement(Window, &win32vars.GlobalWindowPosition); SetWindowPlacement(win, &win32vars.bordered_win_pos);
SetWindowPos(Window, 0, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_NOOWNERZORDER | SWP_FRAMECHANGED); SetWindowPos(win, 0, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_NOOWNERZORDER | SWP_FRAMECHANGED);
win32vars.full_screen = false; win32vars.full_screen = false;
} }
} }
@ -233,15 +235,10 @@ Sys_Show_Mouse_Cursor_Sig(system_show_mouse_cursor){
internal internal
Sys_Set_Fullscreen_Sig(system_set_fullscreen){ Sys_Set_Fullscreen_Sig(system_set_fullscreen){
b32 success = false; // NOTE(allen): If the new value of full_screen does not match the current value,
// HACK(allen): Fix this shit. // set toggle to true.
// NOTE(allen): On windows we must be in stream mode to go fullscreen. win32vars.do_toggle = (win32vars.full_screen != full_screen);
if (plat_settings.stream_mode){ b32 success = true;
// 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); return(success);
} }
@ -732,7 +729,7 @@ Win32InitGL(){
{ {
WGL_DRAW_TO_WINDOW_ARB, TRUE, WGL_DRAW_TO_WINDOW_ARB, TRUE,
WGL_SUPPORT_OPENGL_ARB, TRUE, WGL_SUPPORT_OPENGL_ARB, TRUE,
//WGL_DOUBLE_BUFFER_ARB, GL_TRUE, WGL_DOUBLE_BUFFER_ARB, GL_TRUE,
WGL_PIXEL_TYPE_ARB, WGL_TYPE_RGBA_ARB, WGL_PIXEL_TYPE_ARB, WGL_TYPE_RGBA_ARB,
WGL_COLOR_BITS_ARB, 32, WGL_COLOR_BITS_ARB, 32,
WGL_DEPTH_BITS_ARB, 24, WGL_DEPTH_BITS_ARB, 24,
@ -1081,7 +1078,7 @@ WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdS
memset(&win32vars, 0, sizeof(win32vars)); memset(&win32vars, 0, sizeof(win32vars));
win32vars.GlobalWindowPosition.length = sizeof(win32vars.GlobalWindowPosition); win32vars.bordered_win_pos.length = sizeof(win32vars.bordered_win_pos);
system_init_threaded_work_system(); system_init_threaded_work_system();
@ -1262,13 +1259,12 @@ WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdS
LOGF("Setting window position (%d, %d)\n", window_x, window_y); LOGF("Setting window position (%d, %d)\n", window_x, window_y);
} }
i32 window_style = WS_OVERLAPPEDWINDOW; LOG("Creating window... ");
i32 window_style = WS_CAPTION|WS_MINIMIZEBOX|WS_BORDER;
if (!plat_settings.fullscreen_window && plat_settings.maximize_window){ if (!plat_settings.fullscreen_window && plat_settings.maximize_window){
window_style |= WS_MAXIMIZE; window_style |= WS_MAXIMIZE;
} }
win32vars.window_handle = CreateWindowEx(0, window_class.lpszClassName, WINDOW_NAME, window_style, window_x, window_y, window_rect.right - window_rect.left, window_rect.bottom - window_rect.top, 0, 0, hInstance, 0);
LOG("Creating window... ");
win32vars.window_handle = CreateWindow(window_class.lpszClassName, WINDOW_NAME, window_style, window_x, window_y, window_rect.right - window_rect.left, window_rect.bottom - window_rect.top, 0, 0, hInstance, 0);
if (win32vars.window_handle == 0){ if (win32vars.window_handle == 0){
LOG("Failed\n"); LOG("Failed\n");
@ -1372,13 +1368,7 @@ WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdS
// without interfering with the reading process // without interfering with the reading process
// Looks like we can ReadFile with a size of zero // Looks like we can ReadFile with a size of zero
// in an IOCP for this effect. // in an IOCP for this effect.
if (!win32vars.first){
// NOTE(allen): When we're in stream mode we don't have
// double buffering so we need to move ahead and call
// the first step right away so it will render into the
// window. With double buffering this is not an issue
// for reasons I cannot at all comprehend.
if (!(win32vars.first && plat_settings.stream_mode)){
system_release_lock(FRAME_LOCK); system_release_lock(FRAME_LOCK);
if (win32vars.running_cli == 0){ if (win32vars.running_cli == 0){
@ -1458,7 +1448,7 @@ WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdS
} }
} }
} }
}while(get_more_messages); }while (get_more_messages);
system_acquire_lock(FRAME_LOCK); system_acquire_lock(FRAME_LOCK);
} }

View File

@ -22,23 +22,23 @@ struct Win32_Directory_Listener{
}; };
global_const OVERLAPPED null_overlapped = {0}; global_const OVERLAPPED null_overlapped = {0};
typedef struct { struct Win32_Directory_Listener_Node{
DLL_Node node; DLL_Node node;
Win32_Directory_Listener listener; Win32_Directory_Listener listener;
} Win32_Directory_Listener_Node; };
typedef struct { struct Win32_File_Track_Vars{
HANDLE iocp; HANDLE iocp;
CRITICAL_SECTION table_lock; CRITICAL_SECTION table_lock;
void *tables; void *tables;
DLL_Node free_sentinel; DLL_Node free_sentinel;
} Win32_File_Track_Vars; };
typedef struct { struct Win32_File_Track_Entry{
File_Index hash; File_Index hash;
HANDLE dir; HANDLE dir;
Win32_Directory_Listener_Node *listener_node; Win32_Directory_Listener_Node *listener_node;
} Win32_File_Track_Entry; };
#define to_vars(s) ((Win32_File_Track_Vars*)(s)) #define to_vars(s) ((Win32_File_Track_Vars*)(s))
#define to_tables(v) ((File_Track_Tables*)(v->tables)) #define to_tables(v) ((File_Track_Tables*)(v->tables))