Subversion Repositories eduke32

Rev

Rev 4774 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
3221 hendricks2 1
// Windows layer-independent code
2
 
4535 terminx 3
#include "compat.h"
3221 hendricks2 4
#include "build.h"
5
#include "baselayer.h"
3371 hendricks2 6
#include "osd.h"
3581 hendricks2 7
#include "cache1d.h"
4535 terminx 8
 
9
 
10
 
3221 hendricks2 11
#include "winbits.h"
12
 
4685 hendricks2 13
#ifdef BITNESS64
3278 hendricks2 14
# define EBACKTRACEDLL "ebacktrace1-64.dll"
15
#else
16
# define EBACKTRACEDLL "ebacktrace1.dll"
17
#endif
18
 
3221 hendricks2 19
int32_t backgroundidle = 1;
20
 
21
int64_t win_timerfreq = 0;
22
 
23
char silentvideomodeswitch = 0;
24
 
25
static char taskswitching = 1;
26
 
27
static HANDLE instanceflag = NULL;
28
 
29
static OSVERSIONINFOEX osv;
30
 
3371 hendricks2 31
static int32_t togglecomp = 1;
32
 
3221 hendricks2 33
//
34
// CheckWinVersion() -- check to see what version of Windows we happen to be running under
35
//
36
BOOL CheckWinVersion(void)
37
{
38
    ZeroMemory(&osv, sizeof(osv));
39
    osv.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
40
 
41
    // we don't like anything older than Windows XP
42
 
43
    if (!GetVersionEx((LPOSVERSIONINFOA)&osv)) return FALSE;
44
 
45
    if (osv.dwMajorVersion >= 6) return TRUE;
46
    if (osv.dwMajorVersion == 5 && osv.dwMinorVersion >= 1) return TRUE;
47
 
48
    return FALSE;
49
}
50
 
51
static void win_printversion(void)
52
{
53
    const char *ver = "";
54
 
55
    switch (osv.dwPlatformId)
56
    {
4891 terminx 57
        case VER_PLATFORM_WIN32_NT:
58
            switch (osv.dwMajorVersion)
3221 hendricks2 59
            {
4891 terminx 60
                case 5:
61
                    switch (osv.dwMinorVersion)
62
                    {
63
                        case 1: ver = "XP"; break;
64
                        case 2: ver = osv.wProductType == VER_NT_WORKSTATION ? "XP x64" : "Server 2003"; break;
65
                    }
66
                    break;
3221 hendricks2 67
 
4891 terminx 68
                case 6:
69
                    switch (osv.dwMinorVersion)
70
                    {
71
                        case 0: ver = osv.wProductType == VER_NT_WORKSTATION ? "Vista" : "Server 2008"; break;
72
                        case 1: ver = osv.wProductType == VER_NT_WORKSTATION ? "7" : "Server 2008 R2"; break;
73
                        case 2: ver = osv.wProductType == VER_NT_WORKSTATION ? "8" : "Server 2012"; break;
74
                        case 3: ver = osv.wProductType == VER_NT_WORKSTATION ? "8.1" : "Server 2012 R2"; break;
75
                    }
76
                    break;
77
 
78
                case 10:
79
                    switch (osv.dwMinorVersion)
80
                    {
81
                        case 0: ver = osv.wProductType == VER_NT_WORKSTATION ? "10" : "Server 10"; break;
82
                    }
83
                    break;
3221 hendricks2 84
            }
85
            break;
86
    }
87
 
4086 hendricks2 88
    initprintf("Windows %s", ver);
89
    if (osv.szCSDVersion && osv.szCSDVersion[0])
90
        initprintf(" %s", osv.szCSDVersion);
91
    initprintf(" (build %lu.%lu.%lu)\n", osv.dwMajorVersion, osv.dwMinorVersion, osv.dwBuildNumber);
3221 hendricks2 92
}
93
 
94
//
95
// win_allowtaskswitching() -- captures/releases alt+tab hotkeys
96
//
97
void win_allowtaskswitching(int32_t onf)
98
{
99
    if (onf == taskswitching) return;
100
 
101
    if (onf)
102
    {
103
        UnregisterHotKey(0,0);
104
        UnregisterHotKey(0,1);
105
    }
106
    else
107
    {
108
        RegisterHotKey(0,0,MOD_ALT,VK_TAB);
109
        RegisterHotKey(0,1,MOD_ALT|MOD_SHIFT,VK_TAB);
110
    }
111
 
112
    taskswitching = onf;
113
}
114
 
115
 
116
//
117
// win_checkinstance() -- looks for another instance of a Build app
118
//
119
int32_t win_checkinstance(void)
120
{
121
    if (!instanceflag) return 0;
122
    return (WaitForSingleObject(instanceflag,0) == WAIT_TIMEOUT);
123
}
124
 
125
//
126
// high-resolution timers for profiling
127
//
128
int32_t win_inittimer(void)
129
{
130
    int64_t t;
131
 
132
    if (win_timerfreq) return 0;        // already installed
133
 
134
    // OpenWatcom seems to want us to query the value into a local variable
135
    // instead of the global 'win_timerfreq' or else it gets pissed with an
136
    // access violation
137
    if (!QueryPerformanceFrequency((LARGE_INTEGER *)&t))
138
    {
139
        ShowErrorBox("Failed fetching timer frequency");
140
        return -1;
141
    }
142
    win_timerfreq = t;
143
 
144
    return 0;
145
}
146
 
3934 helixhorne 147
uint64_t win_getu64ticks(void)
3221 hendricks2 148
{
149
    uint64_t i;
150
    if (win_timerfreq == 0) return 0;
151
    QueryPerformanceCounter((LARGE_INTEGER *)&i);
152
    return i;
153
}
154
 
155
 
156
 
157
static void ToggleDesktopComposition(BOOL compEnable)
158
{
159
    static HMODULE              hDWMApiDLL        = NULL;
160
    static HRESULT(WINAPI *aDwmEnableComposition)(UINT);
161
 
162
    if (!hDWMApiDLL && (hDWMApiDLL = LoadLibrary("DWMAPI.DLL")))
163
        aDwmEnableComposition = (HRESULT(WINAPI *)(UINT))GetProcAddress(hDWMApiDLL, "DwmEnableComposition");
164
 
165
    if (aDwmEnableComposition)
166
    {
167
        aDwmEnableComposition(compEnable);
168
        if (!silentvideomodeswitch)
169
            initprintf("%sabling desktop composition...\n", (compEnable) ? "En" : "Dis");
170
    }
171
}
172
 
4538 hendricks2 173
typedef void (*dllSetString)(const char*);
3221 hendricks2 174
 
175
//
176
// win_open(), win_init(), win_setvideomode(), win_uninit(), win_close() -- shared code
177
//
178
void win_open(void)
179
{
4027 terminx 180
#ifdef DEBUGGINGAIDS
4538 hendricks2 181
    HMODULE ebacktrace = LoadLibraryA(EBACKTRACEDLL);
182
    if (ebacktrace)
183
    {
184
        dllSetString SetTechnicalName = (dllSetString) GetProcAddress(ebacktrace, "SetTechnicalName");
185
        dllSetString SetProperName = (dllSetString) GetProcAddress(ebacktrace, "SetProperName");
186
 
187
        if (SetTechnicalName)
188
            SetTechnicalName(AppTechnicalName);
189
 
190
        if (SetProperName)
191
            SetProperName(AppProperName);
192
    }
3221 hendricks2 193
#endif
194
 
195
    instanceflag = CreateSemaphore(NULL, 1,1, WindowClass);
196
}
197
 
198
void win_init(void)
199
{
3371 hendricks2 200
    uint32_t i;
201
 
202
    cvar_t cvars_win[] =
203
    {
3783 terminx 204
        { "r_togglecomposition","enable/disable toggle of desktop composition when initializing screen modes",(void *) &togglecomp, CVAR_BOOL, 0, 1 },
3371 hendricks2 205
    };
206
 
4385 terminx 207
    for (i=0; i<ARRAY_SIZE(cvars_win); i++)
3371 hendricks2 208
    {
209
        if (OSD_RegisterCvar(&cvars_win[i]))
210
            continue;
211
 
212
        OSD_RegisterFunction(cvars_win[i].name, cvars_win[i].desc, osdcmd_cvar_set);
213
    }
214
 
3221 hendricks2 215
    win_printversion();
216
}
217
 
218
void win_setvideomode(int32_t c)
219
{
3371 hendricks2 220
    if (togglecomp && osv.dwMajorVersion == 6 && osv.dwMinorVersion < 2)
3221 hendricks2 221
        ToggleDesktopComposition(c < 16);
222
}
223
 
224
void win_uninit(void)
225
{
226
    win_allowtaskswitching(1);
227
}
228
 
229
void win_close(void)
230
{
231
    if (instanceflag) CloseHandle(instanceflag);
232
}
233
 
234
 
235
//
236
// ShowErrorBox() -- shows an error message box
237
//
238
void ShowErrorBox(const char *m)
239
{
240
    TCHAR msg[1024];
241
 
242
    wsprintf(msg, "%s: %s", m, GetWindowsErrorMsg(GetLastError()));
243
    MessageBox(0, msg, apptitle, MB_OK|MB_ICONSTOP);
244
}
245
 
246
//
247
// GetWindowsErrorMsg() -- gives a pointer to a static buffer containing the Windows error message
248
//
249
LPTSTR GetWindowsErrorMsg(DWORD code)
250
{
251
    static TCHAR lpMsgBuf[1024];
252
 
253
    FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
254
                  NULL, code,
255
                  MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
256
                  (LPTSTR)lpMsgBuf, 1024, NULL);
257
 
258
    return lpMsgBuf;
259
}
260
 
4086 hendricks2 261
 
262
//
263
// Miscellaneous
264
//
265
 
3581 hendricks2 266
int32_t addsearchpath_ProgramFiles(const char *p)
267
{
268
    int32_t returncode = -1, i;
269
    const char *ProgramFiles[2] = { Bgetenv("ProgramFiles"), Bgetenv("ProgramFiles(x86)") };
3221 hendricks2 270
 
3581 hendricks2 271
    for (i = 0; i < 2; ++i)
272
    {
273
        if (ProgramFiles[i])
274
        {
275
            char *buffer = (char*)Bmalloc((strlen(ProgramFiles[i])+1+strlen(p)+1)*sizeof(char));
276
            Bsprintf(buffer,"%s/%s",ProgramFiles[i],p);
277
            if (addsearchpath(buffer) == 0) // if any work, return success
278
                returncode = 0;
279
            Bfree(buffer);
280
        }
281
    }
282
 
283
    return returncode;
284
}
4073 hendricks2 285
 
286
 
287
// Workaround for a bug in mingwrt-4.0.0 and up where a function named main() in misc/src/libcrt/gdtoa/qnan.c takes precedence over the proper one in src/libcrt/crt/main.c.
4685 hendricks2 288
#if (defined __MINGW32__ && EDUKE32_GCC_PREREQ(4,8)) || EDUKE32_CLANG_PREREQ(3,4)
4774 hendricks2 289
# undef main
4073 hendricks2 290
# include "mingw_main.c"
291
#endif