src/video/windows/SDL_windowsmodes.c
author Ryan C. Gordon
Mon, 23 Jan 2017 12:06:10 -0500
changeset 10837 c2f241c2f6ad
parent 10737 3406a0f8b041
child 11218 0060bcf673e8
permissions -rw-r--r--
audio: Fix same bug as last commit, but for _mm_bslli_si128 vs _mm_slli_si128.
slouken@1895
     1
/*
slouken@5535
     2
  Simple DirectMedia Layer
slouken@10737
     3
  Copyright (C) 1997-2017 Sam Lantinga <slouken@libsdl.org>
slouken@1895
     4
slouken@5535
     5
  This software is provided 'as-is', without any express or implied
slouken@5535
     6
  warranty.  In no event will the authors be held liable for any damages
slouken@5535
     7
  arising from the use of this software.
slouken@1895
     8
slouken@5535
     9
  Permission is granted to anyone to use this software for any purpose,
slouken@5535
    10
  including commercial applications, and to alter it and redistribute it
slouken@5535
    11
  freely, subject to the following restrictions:
slouken@1895
    12
slouken@5535
    13
  1. The origin of this software must not be misrepresented; you must not
slouken@5535
    14
     claim that you wrote the original software. If you use this software
slouken@5535
    15
     in a product, an acknowledgment in the product documentation would be
slouken@5535
    16
     appreciated but is not required.
slouken@5535
    17
  2. Altered source versions must be plainly marked as such, and must not be
slouken@5535
    18
     misrepresented as being the original software.
slouken@5535
    19
  3. This notice may not be removed or altered from any source distribution.
slouken@1895
    20
*/
icculus@8093
    21
#include "../../SDL_internal.h"
slouken@1895
    22
slouken@6044
    23
#if SDL_VIDEO_DRIVER_WINDOWS
slouken@6044
    24
slouken@5062
    25
#include "SDL_windowsvideo.h"
icculus@10031
    26
#include "../../../include/SDL_assert.h"
slouken@1895
    27
slouken@5086
    28
/* Windows CE compatibility */
slouken@5086
    29
#ifndef CDS_FULLSCREEN
slouken@5086
    30
#define CDS_FULLSCREEN 0
slouken@5086
    31
#endif
slouken@1895
    32
alfred@9813
    33
typedef struct _WIN_GetMonitorDPIData {
slouken@9889
    34
    SDL_VideoData *vid_data;
slouken@9889
    35
    SDL_DisplayMode *mode;
slouken@9889
    36
    SDL_DisplayModeData *mode_data;
alfred@9813
    37
} WIN_GetMonitorDPIData;
alfred@9813
    38
alfred@9813
    39
static BOOL CALLBACK
alfred@9813
    40
WIN_GetMonitorDPI(HMONITOR hMonitor,
slouken@9889
    41
                  HDC      hdcMonitor,
slouken@9889
    42
                  LPRECT   lprcMonitor,
slouken@9889
    43
                  LPARAM   dwData)
alfred@9813
    44
{
slouken@9889
    45
    WIN_GetMonitorDPIData *data = (WIN_GetMonitorDPIData*) dwData;
slouken@9889
    46
    UINT hdpi, vdpi;
alfred@9813
    47
slouken@9889
    48
    if (data->vid_data->GetDpiForMonitor(hMonitor, MDT_EFFECTIVE_DPI, &hdpi, &vdpi) == S_OK &&
slouken@9889
    49
        hdpi > 0 &&
slouken@9889
    50
        vdpi > 0) {
slouken@9889
    51
        float hsize, vsize;
slouken@9889
    52
        
slouken@9889
    53
        data->mode_data->HorzDPI = (float)hdpi;
slouken@9889
    54
        data->mode_data->VertDPI = (float)vdpi;
alfred@9813
    55
slouken@9889
    56
        // Figure out the monitor size and compute the diagonal DPI.
slouken@9889
    57
        hsize = data->mode->w / data->mode_data->HorzDPI;
slouken@9889
    58
        vsize = data->mode->h / data->mode_data->VertDPI;
slouken@9889
    59
        
slouken@9889
    60
        data->mode_data->DiagDPI = SDL_ComputeDiagonalDPI( data->mode->w,
slouken@9889
    61
                                                           data->mode->h,
slouken@9889
    62
                                                           hsize,
slouken@9889
    63
                                                           vsize );
alfred@9813
    64
slouken@9889
    65
        // We can only handle one DPI per display mode so end the enumeration.
slouken@9889
    66
        return FALSE;
slouken@9889
    67
    }
alfred@9813
    68
slouken@9889
    69
    // We didn't get DPI information so keep going.
slouken@9889
    70
    return TRUE;
alfred@9813
    71
}
alfred@9813
    72
slouken@10117
    73
static void
slouken@10117
    74
WIN_UpdateDisplayMode(_THIS, LPCTSTR deviceName, DWORD index, SDL_DisplayMode * mode)
slouken@1895
    75
{
alfred@9813
    76
    SDL_VideoData *vid_data = (SDL_VideoData *) _this->driverdata;
slouken@10117
    77
    SDL_DisplayModeData *data = (SDL_DisplayModeData *) mode->driverdata;
slouken@1895
    78
    HDC hdc;
slouken@1895
    79
slouken@1895
    80
    data->DeviceMode.dmFields =
slouken@1895
    81
        (DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT | DM_DISPLAYFREQUENCY |
slouken@1895
    82
         DM_DISPLAYFLAGS);
slouken@1895
    83
slouken@1913
    84
    if (index == ENUM_CURRENT_SETTINGS
slouken@1913
    85
        && (hdc = CreateDC(deviceName, NULL, NULL, NULL)) != NULL) {
slouken@1895
    86
        char bmi_data[sizeof(BITMAPINFOHEADER) + 256 * sizeof(RGBQUAD)];
slouken@1895
    87
        LPBITMAPINFO bmi;
slouken@1895
    88
        HBITMAP hbm;
slouken@9889
    89
        int logical_width = GetDeviceCaps( hdc, HORZRES );
slouken@9889
    90
        int logical_height = GetDeviceCaps( hdc, VERTRES );
slouken@8086
    91
slouken@10117
    92
        data->ScaleX = (float)logical_width / data->DeviceMode.dmPelsWidth;
slouken@10117
    93
        data->ScaleY = (float)logical_height / data->DeviceMode.dmPelsHeight;
slouken@9889
    94
        mode->w = logical_width;
slouken@9889
    95
        mode->h = logical_height;
slouken@1895
    96
slouken@9889
    97
        // WIN_GetMonitorDPI needs mode->w and mode->h
slouken@9889
    98
        // so only call after those are set.
slouken@9889
    99
        if (vid_data->GetDpiForMonitor) {
slouken@9889
   100
            WIN_GetMonitorDPIData dpi_data;
alfred@9819
   101
            RECT monitor_rect;
alfred@9813
   102
slouken@9889
   103
            dpi_data.vid_data = vid_data;
slouken@9889
   104
            dpi_data.mode = mode;
slouken@9889
   105
            dpi_data.mode_data = data;
slouken@10117
   106
            monitor_rect.left = data->DeviceMode.dmPosition.x;
slouken@10117
   107
            monitor_rect.top = data->DeviceMode.dmPosition.y;
alfred@9819
   108
            monitor_rect.right = monitor_rect.left + 1;
alfred@9819
   109
            monitor_rect.bottom = monitor_rect.top + 1;
slouken@9889
   110
            EnumDisplayMonitors(NULL, &monitor_rect, WIN_GetMonitorDPI, (LPARAM)&dpi_data);
slouken@9889
   111
        } else {
slouken@9889
   112
            // We don't have the Windows 8.1 routine so just
slouken@9889
   113
            // get system DPI.
slouken@9889
   114
            data->HorzDPI = (float)GetDeviceCaps( hdc, LOGPIXELSX );
slouken@9889
   115
            data->VertDPI = (float)GetDeviceCaps( hdc, LOGPIXELSY );
slouken@9889
   116
            if (data->HorzDPI == data->VertDPI) {
slouken@9889
   117
                data->DiagDPI = data->HorzDPI;
slouken@9889
   118
            } else {
slouken@9889
   119
                data->DiagDPI = SDL_ComputeDiagonalDPI( mode->w,
slouken@9889
   120
                                                        mode->h,
slouken@9889
   121
                                                        (float)GetDeviceCaps( hdc, HORZSIZE ) / 25.4f,
slouken@9889
   122
                                                        (float)GetDeviceCaps( hdc, VERTSIZE ) / 25.4f );
slouken@9889
   123
            }
slouken@9889
   124
        }
slouken@9889
   125
        
slouken@1895
   126
        SDL_zero(bmi_data);
slouken@1895
   127
        bmi = (LPBITMAPINFO) bmi_data;
slouken@1895
   128
        bmi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
slouken@1895
   129
slouken@1895
   130
        hbm = CreateCompatibleBitmap(hdc, 1, 1);
slouken@1895
   131
        GetDIBits(hdc, hbm, 0, 1, NULL, bmi, DIB_RGB_COLORS);
slouken@1895
   132
        GetDIBits(hdc, hbm, 0, 1, NULL, bmi, DIB_RGB_COLORS);
slouken@1895
   133
        DeleteObject(hbm);
slouken@1895
   134
        DeleteDC(hdc);
slouken@1895
   135
        if (bmi->bmiHeader.biCompression == BI_BITFIELDS) {
slouken@1895
   136
            switch (*(Uint32 *) bmi->bmiColors) {
slouken@1895
   137
            case 0x00FF0000:
slouken@1965
   138
                mode->format = SDL_PIXELFORMAT_RGB888;
slouken@1895
   139
                break;
slouken@1895
   140
            case 0x000000FF:
slouken@1965
   141
                mode->format = SDL_PIXELFORMAT_BGR888;
slouken@1895
   142
                break;
slouken@1895
   143
            case 0xF800:
slouken@1965
   144
                mode->format = SDL_PIXELFORMAT_RGB565;
slouken@1895
   145
                break;
slouken@1895
   146
            case 0x7C00:
slouken@1965
   147
                mode->format = SDL_PIXELFORMAT_RGB555;
slouken@1895
   148
                break;
slouken@1895
   149
            }
slouken@1895
   150
        } else if (bmi->bmiHeader.biBitCount == 8) {
slouken@1965
   151
            mode->format = SDL_PIXELFORMAT_INDEX8;
lestat@3175
   152
        } else if (bmi->bmiHeader.biBitCount == 4) {
lestat@3175
   153
            mode->format = SDL_PIXELFORMAT_INDEX4LSB;
slouken@1895
   154
        }
slouken@10117
   155
    } else if (mode->format == SDL_PIXELFORMAT_UNKNOWN) {
slouken@1913
   156
        /* FIXME: Can we tell what this will be? */
slouken@10117
   157
        if ((data->DeviceMode.dmFields & DM_BITSPERPEL) == DM_BITSPERPEL) {
slouken@10117
   158
            switch (data->DeviceMode.dmBitsPerPel) {
lestat@3175
   159
            case 32:
lestat@3175
   160
                mode->format = SDL_PIXELFORMAT_RGB888;
lestat@3175
   161
                break;
lestat@3175
   162
            case 24:
lestat@3175
   163
                mode->format = SDL_PIXELFORMAT_RGB24;
lestat@3175
   164
                break;
lestat@3175
   165
            case 16:
lestat@3175
   166
                mode->format = SDL_PIXELFORMAT_RGB565;
lestat@3175
   167
                break;
lestat@3175
   168
            case 15:
lestat@3175
   169
                mode->format = SDL_PIXELFORMAT_RGB555;
lestat@3175
   170
                break;
lestat@3175
   171
            case 8:
lestat@3175
   172
                mode->format = SDL_PIXELFORMAT_INDEX8;
lestat@3175
   173
                break;
lestat@3175
   174
            case 4:
lestat@3175
   175
                mode->format = SDL_PIXELFORMAT_INDEX4LSB;
lestat@3175
   176
                break;
lestat@3175
   177
            }
slouken@3186
   178
        }
slouken@1895
   179
    }
slouken@10117
   180
}
slouken@10117
   181
slouken@10117
   182
static SDL_bool
slouken@10117
   183
WIN_GetDisplayMode(_THIS, LPCTSTR deviceName, DWORD index, SDL_DisplayMode * mode)
slouken@10117
   184
{
slouken@10117
   185
    SDL_DisplayModeData *data;
slouken@10117
   186
    DEVMODE devmode;
slouken@10117
   187
slouken@10117
   188
    devmode.dmSize = sizeof(devmode);
slouken@10117
   189
    devmode.dmDriverExtra = 0;
slouken@10117
   190
    if (!EnumDisplaySettings(deviceName, index, &devmode)) {
slouken@10117
   191
        return SDL_FALSE;
slouken@10117
   192
    }
slouken@10117
   193
slouken@10117
   194
    data = (SDL_DisplayModeData *) SDL_malloc(sizeof(*data));
slouken@10117
   195
    if (!data) {
slouken@10117
   196
        return SDL_FALSE;
slouken@10117
   197
    }
slouken@10117
   198
slouken@10117
   199
    mode->driverdata = data;
slouken@10117
   200
    data->DeviceMode = devmode;
slouken@10117
   201
slouken@10117
   202
    /* Default basic information */
slouken@10117
   203
    data->ScaleX = 1.0f;
slouken@10117
   204
    data->ScaleY = 1.0f;
slouken@10117
   205
    data->DiagDPI = 0.0f;
slouken@10117
   206
    data->HorzDPI = 0.0f;
slouken@10117
   207
    data->VertDPI = 0.0f;
slouken@10117
   208
slouken@10117
   209
    mode->format = SDL_PIXELFORMAT_UNKNOWN;
slouken@10117
   210
    mode->w = data->DeviceMode.dmPelsWidth;
slouken@10117
   211
    mode->h = data->DeviceMode.dmPelsHeight;
slouken@10117
   212
    mode->refresh_rate = data->DeviceMode.dmDisplayFrequency;
slouken@10117
   213
slouken@10117
   214
    /* Fill in the mode information */
slouken@10117
   215
    WIN_UpdateDisplayMode(_this, deviceName, index, mode);
slouken@1895
   216
    return SDL_TRUE;
slouken@1895
   217
}
slouken@1895
   218
slouken@2149
   219
static SDL_bool
alfred@9813
   220
WIN_AddDisplay(_THIS, LPTSTR DeviceName)
slouken@2119
   221
{
slouken@2119
   222
    SDL_VideoDisplay display;
slouken@2119
   223
    SDL_DisplayData *displaydata;
slouken@2119
   224
    SDL_DisplayMode mode;
slouken@6793
   225
    DISPLAY_DEVICE device;
slouken@2119
   226
slouken@2119
   227
#ifdef DEBUG_MODES
slouken@2119
   228
    printf("Display: %s\n", WIN_StringToUTF8(DeviceName));
slouken@2119
   229
#endif
alfred@9813
   230
    if (!WIN_GetDisplayMode(_this, DeviceName, ENUM_CURRENT_SETTINGS, &mode)) {
slouken@2149
   231
        return SDL_FALSE;
slouken@2119
   232
    }
slouken@2119
   233
slouken@2119
   234
    displaydata = (SDL_DisplayData *) SDL_malloc(sizeof(*displaydata));
slouken@2119
   235
    if (!displaydata) {
slouken@2149
   236
        return SDL_FALSE;
slouken@2119
   237
    }
slouken@2119
   238
    SDL_memcpy(displaydata->DeviceName, DeviceName,
slouken@2119
   239
               sizeof(displaydata->DeviceName));
slouken@2119
   240
slouken@2119
   241
    SDL_zero(display);
slouken@6793
   242
    device.cb = sizeof(device);
slouken@6793
   243
    if (EnumDisplayDevices(DeviceName, 0, &device, 0)) {
slouken@6793
   244
        display.name = WIN_StringToUTF8(device.DeviceString);
slouken@6793
   245
    }
slouken@2119
   246
    display.desktop_mode = mode;
slouken@2119
   247
    display.current_mode = mode;
slouken@2119
   248
    display.driverdata = displaydata;
slouken@2119
   249
    SDL_AddVideoDisplay(&display);
slouken@6793
   250
    SDL_free(display.name);
slouken@2149
   251
    return SDL_TRUE;
slouken@2119
   252
}
slouken@2119
   253
slouken@3521
   254
int
slouken@1895
   255
WIN_InitModes(_THIS)
slouken@1895
   256
{
slouken@5305
   257
    int pass;
slouken@2149
   258
    DWORD i, j, count;
slouken@1895
   259
    DISPLAY_DEVICE device;
slouken@1895
   260
slouken@1895
   261
    device.cb = sizeof(device);
slouken@1895
   262
slouken@5305
   263
    /* Get the primary display in the first pass */
slouken@5305
   264
    for (pass = 0; pass < 2; ++pass) {
slouken@5305
   265
        for (i = 0; ; ++i) {
slouken@5305
   266
            TCHAR DeviceName[32];
slouken@5305
   267
slouken@5305
   268
            if (!EnumDisplayDevices(NULL, i, &device, 0)) {
slouken@1895
   269
                break;
slouken@1895
   270
            }
slouken@1895
   271
            if (!(device.StateFlags & DISPLAY_DEVICE_ATTACHED_TO_DESKTOP)) {
slouken@1895
   272
                continue;
slouken@1895
   273
            }
slouken@5305
   274
            if (pass == 0) {
slouken@5305
   275
                if (!(device.StateFlags & DISPLAY_DEVICE_PRIMARY_DEVICE)) {
slouken@5305
   276
                    continue;
slouken@5305
   277
                }
slouken@5305
   278
            } else {
slouken@5305
   279
                if (device.StateFlags & DISPLAY_DEVICE_PRIMARY_DEVICE) {
slouken@5305
   280
                    continue;
slouken@5305
   281
                }
slouken@5305
   282
            }
slouken@5305
   283
            SDL_memcpy(DeviceName, device.DeviceName, sizeof(DeviceName));
slouken@5305
   284
#ifdef DEBUG_MODES
slouken@5305
   285
            printf("Device: %s\n", WIN_StringToUTF8(DeviceName));
slouken@5305
   286
#endif
slouken@5305
   287
            count = 0;
slouken@5305
   288
            for (j = 0; ; ++j) {
slouken@5305
   289
                if (!EnumDisplayDevices(DeviceName, j, &device, 0)) {
slouken@5305
   290
                    break;
slouken@5305
   291
                }
slouken@5305
   292
                if (!(device.StateFlags & DISPLAY_DEVICE_ATTACHED_TO_DESKTOP)) {
slouken@5305
   293
                    continue;
slouken@5305
   294
                }
slouken@5305
   295
                if (pass == 0) {
slouken@5305
   296
                    if (!(device.StateFlags & DISPLAY_DEVICE_PRIMARY_DEVICE)) {
slouken@5305
   297
                        continue;
slouken@5305
   298
                    }
slouken@5305
   299
                } else {
slouken@5305
   300
                    if (device.StateFlags & DISPLAY_DEVICE_PRIMARY_DEVICE) {
slouken@5305
   301
                        continue;
slouken@5305
   302
                    }
slouken@5305
   303
                }
alfred@9813
   304
                count += WIN_AddDisplay(_this, device.DeviceName);
slouken@5305
   305
            }
slouken@5305
   306
            if (count == 0) {
alfred@9813
   307
                WIN_AddDisplay(_this, DeviceName);
slouken@5305
   308
            }
slouken@1895
   309
        }
slouken@1895
   310
    }
slouken@3521
   311
    if (_this->num_displays == 0) {
icculus@7037
   312
        return SDL_SetError("No displays available");
slouken@3521
   313
    }
slouken@3521
   314
    return 0;
slouken@1895
   315
}
slouken@1895
   316
slouken@3528
   317
int
slouken@3528
   318
WIN_GetDisplayBounds(_THIS, SDL_VideoDisplay * display, SDL_Rect * rect)
slouken@3528
   319
{
slouken@5305
   320
    SDL_DisplayModeData *data = (SDL_DisplayModeData *) display->current_mode.driverdata;
slouken@3528
   321
slouken@8086
   322
    rect->x = (int)SDL_ceil(data->DeviceMode.dmPosition.x * data->ScaleX);
slouken@8086
   323
    rect->y = (int)SDL_ceil(data->DeviceMode.dmPosition.y * data->ScaleY);
slouken@8086
   324
    rect->w = (int)SDL_ceil(data->DeviceMode.dmPelsWidth * data->ScaleX);
slouken@8086
   325
    rect->h = (int)SDL_ceil(data->DeviceMode.dmPelsHeight * data->ScaleY);
icculus@6430
   326
slouken@3528
   327
    return 0;
slouken@3528
   328
}
slouken@3528
   329
alfred@9813
   330
int
alfred@9813
   331
WIN_GetDisplayDPI(_THIS, SDL_VideoDisplay * display, float * ddpi, float * hdpi, float * vdpi)
alfred@9813
   332
{
alfred@9813
   333
    SDL_DisplayModeData *data = (SDL_DisplayModeData *) display->current_mode.driverdata;
alfred@9813
   334
slouken@9889
   335
    if (ddpi) {
slouken@9889
   336
        *ddpi = data->DiagDPI;
slouken@9889
   337
    }
slouken@9889
   338
    if (hdpi) {
slouken@9889
   339
        *hdpi = data->HorzDPI;
slouken@9889
   340
    }
slouken@9889
   341
    if (vdpi) {
slouken@9889
   342
        *vdpi = data->VertDPI;
slouken@9889
   343
    }
alfred@9813
   344
philipp@10174
   345
    return data->DiagDPI != 0.0f ? 0 : SDL_SetError("Couldn't get DPI");
alfred@9813
   346
}
alfred@9813
   347
icculus@10019
   348
int
icculus@10019
   349
WIN_GetDisplayUsableBounds(_THIS, SDL_VideoDisplay * display, SDL_Rect * rect)
icculus@10019
   350
{
icculus@10019
   351
    const SDL_DisplayModeData *data = (const SDL_DisplayModeData *) display->current_mode.driverdata;
icculus@10019
   352
    const DEVMODE *pDevMode = &data->DeviceMode;
icculus@10019
   353
    POINT pt = {
icculus@10019
   354
        /* !!! FIXME: no scale, right? */
icculus@10019
   355
        (LONG) (pDevMode->dmPosition.x + (pDevMode->dmPelsWidth / 2)),
icculus@10019
   356
        (LONG) (pDevMode->dmPosition.y + (pDevMode->dmPelsHeight / 2))
icculus@10019
   357
    };
icculus@10031
   358
    HMONITOR hmon = MonitorFromPoint(pt, MONITOR_DEFAULTTONULL);
icculus@10019
   359
    MONITORINFO minfo;
icculus@10019
   360
    const RECT *work;
icculus@10019
   361
    BOOL rc = FALSE;
icculus@10019
   362
icculus@10019
   363
    SDL_assert(hmon != NULL);
icculus@10019
   364
icculus@10019
   365
    if (hmon != NULL) {
icculus@10019
   366
        SDL_zero(minfo);
icculus@10019
   367
        minfo.cbSize = sizeof (MONITORINFO);
icculus@10019
   368
        rc = GetMonitorInfo(hmon, &minfo);
icculus@10019
   369
        SDL_assert(rc);
icculus@10019
   370
    }
icculus@10019
   371
icculus@10019
   372
    if (!rc) {
icculus@10019
   373
        return SDL_SetError("Couldn't find monitor data");
icculus@10019
   374
    }
icculus@10019
   375
icculus@10031
   376
    work = &minfo.rcWork;
icculus@10019
   377
    rect->x = (int)SDL_ceil(work->left * data->ScaleX);
icculus@10019
   378
    rect->y = (int)SDL_ceil(work->top * data->ScaleY);
icculus@10019
   379
    rect->w = (int)SDL_ceil((work->right - work->left) * data->ScaleX);
icculus@10019
   380
    rect->h = (int)SDL_ceil((work->bottom - work->top) * data->ScaleY);
icculus@10019
   381
icculus@10019
   382
    return 0;
icculus@10019
   383
}
icculus@10019
   384
slouken@1895
   385
void
slouken@3500
   386
WIN_GetDisplayModes(_THIS, SDL_VideoDisplay * display)
slouken@1895
   387
{
slouken@3500
   388
    SDL_DisplayData *data = (SDL_DisplayData *) display->driverdata;
slouken@1895
   389
    DWORD i;
slouken@1895
   390
    SDL_DisplayMode mode;
slouken@1895
   391
slouken@1895
   392
    for (i = 0;; ++i) {
alfred@9813
   393
        if (!WIN_GetDisplayMode(_this, data->DeviceName, i, &mode)) {
slouken@1895
   394
            break;
slouken@1895
   395
        }
slouken@5305
   396
        if (SDL_ISPIXELFORMAT_INDEXED(mode.format)) {
slouken@5305
   397
            /* We don't support palettized modes now */
gabomdq@7102
   398
            SDL_free(mode.driverdata);
slouken@5305
   399
            continue;
slouken@5305
   400
        }
slouken@3521
   401
        if (mode.format != SDL_PIXELFORMAT_UNKNOWN) {
slouken@3500
   402
            if (!SDL_AddDisplayMode(display, &mode)) {
lestat@3175
   403
                SDL_free(mode.driverdata);
slouken@3186
   404
            }
slouken@8086
   405
        } else {
gabomdq@7102
   406
            SDL_free(mode.driverdata);
gabomdq@7102
   407
        }
slouken@1895
   408
    }
slouken@1895
   409
}
slouken@1895
   410
slouken@1895
   411
int
slouken@3500
   412
WIN_SetDisplayMode(_THIS, SDL_VideoDisplay * display, SDL_DisplayMode * mode)
slouken@1895
   413
{
slouken@3500
   414
    SDL_DisplayData *displaydata = (SDL_DisplayData *) display->driverdata;
slouken@1895
   415
    SDL_DisplayModeData *data = (SDL_DisplayModeData *) mode->driverdata;
slouken@1895
   416
    LONG status;
slouken@3139
   417
slouken@8795
   418
    if (mode->driverdata == display->desktop_mode.driverdata) {
slime73@10179
   419
        status = ChangeDisplaySettingsEx(displaydata->DeviceName, NULL, NULL, CDS_FULLSCREEN, NULL);
slouken@8795
   420
    } else {
slouken@8795
   421
        status = ChangeDisplaySettingsEx(displaydata->DeviceName, &data->DeviceMode, NULL, CDS_FULLSCREEN, NULL);
slouken@8795
   422
    }
slouken@5305
   423
    if (status != DISP_CHANGE_SUCCESSFUL) {
slouken@1895
   424
        const char *reason = "Unknown reason";
slouken@1895
   425
        switch (status) {
slouken@1895
   426
        case DISP_CHANGE_BADFLAGS:
slouken@1895
   427
            reason = "DISP_CHANGE_BADFLAGS";
slouken@1895
   428
            break;
slouken@1895
   429
        case DISP_CHANGE_BADMODE:
slouken@1895
   430
            reason = "DISP_CHANGE_BADMODE";
slouken@1895
   431
            break;
slouken@1895
   432
        case DISP_CHANGE_BADPARAM:
slouken@1895
   433
            reason = "DISP_CHANGE_BADPARAM";
slouken@1895
   434
            break;
slouken@1895
   435
        case DISP_CHANGE_FAILED:
slouken@1895
   436
            reason = "DISP_CHANGE_FAILED";
slouken@1895
   437
            break;
slouken@1895
   438
        }
icculus@7037
   439
        return SDL_SetError("ChangeDisplaySettingsEx() failed: %s", reason);
slouken@1895
   440
    }
slouken@5305
   441
    EnumDisplaySettings(displaydata->DeviceName, ENUM_CURRENT_SETTINGS, &data->DeviceMode);
slouken@10117
   442
    WIN_UpdateDisplayMode(_this, displaydata->DeviceName, ENUM_CURRENT_SETTINGS, mode);
slouken@5305
   443
    return 0;
slouken@1895
   444
}
slouken@1895
   445
slouken@1895
   446
void
slouken@1895
   447
WIN_QuitModes(_THIS)
slouken@1895
   448
{
slouken@5305
   449
    /* All fullscreen windows should have restored modes by now */
slouken@1895
   450
}
slouken@1895
   451
slouken@6044
   452
#endif /* SDL_VIDEO_DRIVER_WINDOWS */
slouken@6044
   453
slouken@1895
   454
/* vi: set ts=4 sw=4 expandtab: */