src/video/windows/SDL_windowsmodes.c
author Sam Lantinga
Tue, 08 Feb 2011 16:50:51 -0800
changeset 5229 c015d3e63631
parent 5149 be02be2ea897
child 5250 f908e06b3c96
permissions -rw-r--r--
Fixed setting the texture unit, still doesn't work.
slouken@1895
     1
/*
slouken@1895
     2
    SDL - Simple DirectMedia Layer
slouken@3697
     3
    Copyright (C) 1997-2010 Sam Lantinga
slouken@1895
     4
slouken@1895
     5
    This library is free software; you can redistribute it and/or
slouken@1895
     6
    modify it under the terms of the GNU Lesser General Public
slouken@1895
     7
    License as published by the Free Software Foundation; either
slouken@1895
     8
    version 2.1 of the License, or (at your option) any later version.
slouken@1895
     9
slouken@1895
    10
    This library is distributed in the hope that it will be useful,
slouken@1895
    11
    but WITHOUT ANY WARRANTY; without even the implied warranty of
slouken@1895
    12
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
slouken@1895
    13
    Lesser General Public License for more details.
slouken@1895
    14
slouken@1895
    15
    You should have received a copy of the GNU Lesser General Public
slouken@1895
    16
    License along with this library; if not, write to the Free Software
slouken@1895
    17
    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
slouken@1895
    18
slouken@1895
    19
    Sam Lantinga
slouken@1895
    20
    slouken@libsdl.org
slouken@1895
    21
*/
slouken@1895
    22
#include "SDL_config.h"
slouken@1895
    23
slouken@5062
    24
#include "SDL_windowsvideo.h"
slouken@1895
    25
slouken@5086
    26
/* Windows CE compatibility */
slouken@5086
    27
#ifndef CDS_FULLSCREEN
slouken@5086
    28
#define CDS_FULLSCREEN 0
slouken@5086
    29
#endif
slouken@1895
    30
slouken@1895
    31
static SDL_bool
slouken@1895
    32
WIN_GetDisplayMode(LPCTSTR deviceName, DWORD index, SDL_DisplayMode * mode)
slouken@1895
    33
{
slouken@1895
    34
    SDL_DisplayModeData *data;
slouken@1895
    35
    DEVMODE devmode;
slouken@5086
    36
#ifndef _WIN32_WCE
slouken@1895
    37
    HDC hdc;
slouken@5086
    38
#endif
slouken@1895
    39
slouken@1895
    40
    devmode.dmSize = sizeof(devmode);
slouken@1895
    41
    devmode.dmDriverExtra = 0;
slouken@1895
    42
    if (!EnumDisplaySettings(deviceName, index, &devmode)) {
slouken@1895
    43
        return SDL_FALSE;
slouken@1895
    44
    }
slouken@1895
    45
slouken@1895
    46
    data = (SDL_DisplayModeData *) SDL_malloc(sizeof(*data));
slouken@1895
    47
    if (!data) {
slouken@1895
    48
        return SDL_FALSE;
slouken@1895
    49
    }
slouken@1895
    50
    data->DeviceMode = devmode;
slouken@1895
    51
    data->DeviceMode.dmFields =
slouken@1895
    52
        (DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT | DM_DISPLAYFREQUENCY |
slouken@1895
    53
         DM_DISPLAYFLAGS);
slouken@1895
    54
slouken@1895
    55
    /* Fill in the mode information */
slouken@1965
    56
    mode->format = SDL_PIXELFORMAT_UNKNOWN;
slouken@1895
    57
    mode->w = devmode.dmPelsWidth;
slouken@1895
    58
    mode->h = devmode.dmPelsHeight;
slouken@1895
    59
    mode->refresh_rate = devmode.dmDisplayFrequency;
slouken@1895
    60
    mode->driverdata = data;
slouken@3097
    61
#ifdef _WIN32_WCE
slouken@3097
    62
    /* In WinCE EnumDisplaySettings(ENUM_CURRENT_SETTINGS) doesn't take the user defined orientation
slouken@3528
    63
       into account but GetSystemMetrics does. */
slouken@3139
    64
    if (index == ENUM_CURRENT_SETTINGS) {
slouken@3139
    65
        mode->w = GetSystemMetrics(SM_CXSCREEN);
slouken@3139
    66
        mode->h = GetSystemMetrics(SM_CYSCREEN);
slouken@3097
    67
    }
slouken@3097
    68
#endif
slouken@1895
    69
slouken@3097
    70
/* WinCE has no GetDIBits, therefore we can't use it to get the display format */
slouken@3097
    71
#ifndef _WIN32_WCE
slouken@1913
    72
    if (index == ENUM_CURRENT_SETTINGS
slouken@1913
    73
        && (hdc = CreateDC(deviceName, NULL, NULL, NULL)) != NULL) {
slouken@1895
    74
        char bmi_data[sizeof(BITMAPINFOHEADER) + 256 * sizeof(RGBQUAD)];
slouken@1895
    75
        LPBITMAPINFO bmi;
slouken@1895
    76
        HBITMAP hbm;
slouken@1895
    77
slouken@1895
    78
        SDL_zero(bmi_data);
slouken@1895
    79
        bmi = (LPBITMAPINFO) bmi_data;
slouken@1895
    80
        bmi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
slouken@1895
    81
slouken@1895
    82
        hbm = CreateCompatibleBitmap(hdc, 1, 1);
slouken@1895
    83
        GetDIBits(hdc, hbm, 0, 1, NULL, bmi, DIB_RGB_COLORS);
slouken@1895
    84
        GetDIBits(hdc, hbm, 0, 1, NULL, bmi, DIB_RGB_COLORS);
slouken@1895
    85
        DeleteObject(hbm);
slouken@1895
    86
        DeleteDC(hdc);
slouken@1895
    87
        if (bmi->bmiHeader.biCompression == BI_BITFIELDS) {
slouken@1895
    88
            switch (*(Uint32 *) bmi->bmiColors) {
slouken@1895
    89
            case 0x00FF0000:
slouken@1965
    90
                mode->format = SDL_PIXELFORMAT_RGB888;
slouken@1895
    91
                break;
slouken@1895
    92
            case 0x000000FF:
slouken@1965
    93
                mode->format = SDL_PIXELFORMAT_BGR888;
slouken@1895
    94
                break;
slouken@1895
    95
            case 0xF800:
slouken@1965
    96
                mode->format = SDL_PIXELFORMAT_RGB565;
slouken@1895
    97
                break;
slouken@1895
    98
            case 0x7C00:
slouken@1965
    99
                mode->format = SDL_PIXELFORMAT_RGB555;
slouken@1895
   100
                break;
slouken@1895
   101
            }
slouken@1895
   102
        } else if (bmi->bmiHeader.biBitCount == 8) {
slouken@1965
   103
            mode->format = SDL_PIXELFORMAT_INDEX8;
lestat@3175
   104
        } else if (bmi->bmiHeader.biBitCount == 4) {
lestat@3175
   105
            mode->format = SDL_PIXELFORMAT_INDEX4LSB;
slouken@1895
   106
        }
slouken@3097
   107
    } else
slouken@3097
   108
#endif /* _WIN32_WCE */
slouken@3097
   109
    {
slouken@1913
   110
        /* FIXME: Can we tell what this will be? */
slouken@3186
   111
        if ((devmode.dmFields & DM_BITSPERPEL) == DM_BITSPERPEL) {
lestat@3175
   112
            switch (devmode.dmBitsPerPel) {
lestat@3175
   113
            case 32:
lestat@3175
   114
                mode->format = SDL_PIXELFORMAT_RGB888;
lestat@3175
   115
                break;
lestat@3175
   116
            case 24:
lestat@3175
   117
                mode->format = SDL_PIXELFORMAT_RGB24;
lestat@3175
   118
                break;
lestat@3175
   119
            case 16:
lestat@3175
   120
                mode->format = SDL_PIXELFORMAT_RGB565;
lestat@3175
   121
                break;
lestat@3175
   122
            case 15:
lestat@3175
   123
                mode->format = SDL_PIXELFORMAT_RGB555;
lestat@3175
   124
                break;
lestat@3175
   125
            case 8:
lestat@3175
   126
                mode->format = SDL_PIXELFORMAT_INDEX8;
lestat@3175
   127
                break;
lestat@3175
   128
            case 4:
lestat@3175
   129
                mode->format = SDL_PIXELFORMAT_INDEX4LSB;
lestat@3175
   130
                break;
lestat@3175
   131
            }
slouken@3186
   132
        }
slouken@1895
   133
    }
slouken@5149
   134
    if (SDL_ISPIXELFORMAT_INDEXED(mode->format)) {
slouken@5149
   135
        /* We don't support palettized modes now */
slouken@5149
   136
        return SDL_FALSE;
slouken@5149
   137
    }
slouken@1895
   138
    return SDL_TRUE;
slouken@1895
   139
}
slouken@1895
   140
slouken@2149
   141
static SDL_bool
slouken@2119
   142
WIN_AddDisplay(LPTSTR DeviceName)
slouken@2119
   143
{
slouken@2119
   144
    SDL_VideoDisplay display;
slouken@2119
   145
    SDL_DisplayData *displaydata;
slouken@2119
   146
    SDL_DisplayMode mode;
slouken@2119
   147
slouken@2119
   148
#ifdef DEBUG_MODES
slouken@2119
   149
    printf("Display: %s\n", WIN_StringToUTF8(DeviceName));
slouken@2119
   150
#endif
slouken@2119
   151
    if (!WIN_GetDisplayMode(DeviceName, ENUM_CURRENT_SETTINGS, &mode)) {
slouken@2149
   152
        return SDL_FALSE;
slouken@2119
   153
    }
slouken@2119
   154
slouken@2119
   155
    displaydata = (SDL_DisplayData *) SDL_malloc(sizeof(*displaydata));
slouken@2119
   156
    if (!displaydata) {
slouken@2149
   157
        return SDL_FALSE;
slouken@2119
   158
    }
slouken@2119
   159
    SDL_memcpy(displaydata->DeviceName, DeviceName,
slouken@2119
   160
               sizeof(displaydata->DeviceName));
slouken@2119
   161
slouken@2119
   162
    SDL_zero(display);
slouken@2119
   163
    display.desktop_mode = mode;
slouken@2119
   164
    display.current_mode = mode;
slouken@2119
   165
    display.driverdata = displaydata;
slouken@2119
   166
    SDL_AddVideoDisplay(&display);
slouken@2149
   167
    return SDL_TRUE;
slouken@2119
   168
}
slouken@2119
   169
slouken@3521
   170
int
slouken@1895
   171
WIN_InitModes(_THIS)
slouken@1895
   172
{
slouken@2149
   173
    DWORD i, j, count;
slouken@1895
   174
    DISPLAY_DEVICE device;
slouken@1895
   175
slouken@1895
   176
    device.cb = sizeof(device);
slouken@1895
   177
    for (i = 0;; ++i) {
slouken@1895
   178
        TCHAR DeviceName[32];
slouken@1895
   179
slouken@1895
   180
        if (!EnumDisplayDevices(NULL, i, &device, 0)) {
slouken@1895
   181
            break;
slouken@1895
   182
        }
slouken@1895
   183
        if (!(device.StateFlags & DISPLAY_DEVICE_ATTACHED_TO_DESKTOP)) {
slouken@1895
   184
            continue;
slouken@1895
   185
        }
slouken@1895
   186
        SDL_memcpy(DeviceName, device.DeviceName, sizeof(DeviceName));
slouken@1895
   187
#ifdef DEBUG_MODES
slouken@1895
   188
        printf("Device: %s\n", WIN_StringToUTF8(DeviceName));
slouken@1895
   189
#endif
slouken@2149
   190
        count = 0;
slouken@1895
   191
        for (j = 0;; ++j) {
slouken@1895
   192
            if (!EnumDisplayDevices(DeviceName, j, &device, 0)) {
slouken@1895
   193
                break;
slouken@1895
   194
            }
slouken@1895
   195
            if (!(device.StateFlags & DISPLAY_DEVICE_ATTACHED_TO_DESKTOP)) {
slouken@1895
   196
                continue;
slouken@1895
   197
            }
slouken@2149
   198
            count += WIN_AddDisplay(device.DeviceName);
slouken@2119
   199
        }
slouken@2149
   200
        if (count == 0) {
slouken@2119
   201
            WIN_AddDisplay(DeviceName);
slouken@1895
   202
        }
slouken@1895
   203
    }
slouken@3521
   204
    if (_this->num_displays == 0) {
slouken@3521
   205
        SDL_SetError("No displays available");
slouken@3521
   206
        return -1;
slouken@3521
   207
    }
slouken@3521
   208
    return 0;
slouken@1895
   209
}
slouken@1895
   210
slouken@3528
   211
int
slouken@3528
   212
WIN_GetDisplayBounds(_THIS, SDL_VideoDisplay * display, SDL_Rect * rect)
slouken@3528
   213
{
slouken@3528
   214
    SDL_DisplayModeData *data = (SDL_DisplayModeData *) display->desktop_mode.driverdata;
slouken@3528
   215
slouken@4569
   216
#ifdef _WIN32_WCE
slouken@4569
   217
    // WINCE: DEVMODE.dmPosition not found, or may be mingw32ce bug
slouken@4569
   218
    rect->x = 0;
slouken@4569
   219
    rect->y = 0;
slouken@4569
   220
    rect->w = display->windows->w;
slouken@4569
   221
    rect->h = display->windows->h;
slouken@4569
   222
#else
slouken@3528
   223
    rect->x = (int)data->DeviceMode.dmPosition.x;
slouken@3528
   224
    rect->y = (int)data->DeviceMode.dmPosition.y;
slouken@3528
   225
    rect->w = data->DeviceMode.dmPelsWidth;
slouken@3528
   226
    rect->h = data->DeviceMode.dmPelsHeight;
slouken@4569
   227
#endif
slouken@3528
   228
    return 0;
slouken@3528
   229
}
slouken@3528
   230
slouken@1895
   231
void
slouken@3500
   232
WIN_GetDisplayModes(_THIS, SDL_VideoDisplay * display)
slouken@1895
   233
{
slouken@3500
   234
    SDL_DisplayData *data = (SDL_DisplayData *) display->driverdata;
slouken@1895
   235
    DWORD i;
slouken@1895
   236
    SDL_DisplayMode mode;
slouken@1895
   237
slouken@1895
   238
    for (i = 0;; ++i) {
slouken@1895
   239
        if (!WIN_GetDisplayMode(data->DeviceName, i, &mode)) {
slouken@1895
   240
            break;
slouken@1895
   241
        }
slouken@3521
   242
        if (mode.format != SDL_PIXELFORMAT_UNKNOWN) {
slouken@3500
   243
            if (!SDL_AddDisplayMode(display, &mode)) {
lestat@3175
   244
                SDL_free(mode.driverdata);
slouken@3186
   245
            }
slouken@3521
   246
        }
slouken@1895
   247
    }
slouken@1895
   248
}
slouken@1895
   249
slouken@1895
   250
int
slouken@3500
   251
WIN_SetDisplayMode(_THIS, SDL_VideoDisplay * display, SDL_DisplayMode * mode)
slouken@1895
   252
{
slouken@3500
   253
    SDL_DisplayData *displaydata = (SDL_DisplayData *) display->driverdata;
slouken@1895
   254
    SDL_DisplayModeData *data = (SDL_DisplayModeData *) mode->driverdata;
slouken@1895
   255
    LONG status;
slouken@3139
   256
slouken@3097
   257
#ifdef _WIN32_WCE
slouken@3097
   258
    /* TODO: implement correctly.
slouken@3097
   259
       On my Asus MyPAL, if I execute the code below
slouken@3097
   260
       I get DISP_CHANGE_BADFLAGS and the Titlebar of the fullscreen window stays
slouken@3139
   261
       visible ... (SDL_RaiseWindow() would fix that one) */
slouken@3097
   262
    return 0;
slouken@3097
   263
#endif
slouken@1895
   264
slouken@1895
   265
    status =
slouken@3500
   266
        ChangeDisplaySettingsEx(displaydata->DeviceName, &data->DeviceMode,
slouken@3500
   267
                                NULL, CDS_FULLSCREEN, NULL);
slouken@1895
   268
    if (status == DISP_CHANGE_SUCCESSFUL) {
slouken@1895
   269
        return 0;
slouken@1895
   270
    } else {
slouken@1895
   271
        const char *reason = "Unknown reason";
slouken@1895
   272
        switch (status) {
slouken@1895
   273
        case DISP_CHANGE_BADFLAGS:
slouken@1895
   274
            reason = "DISP_CHANGE_BADFLAGS";
slouken@1895
   275
            break;
slouken@1895
   276
        case DISP_CHANGE_BADMODE:
slouken@1895
   277
            reason = "DISP_CHANGE_BADMODE";
slouken@1895
   278
            break;
slouken@1895
   279
        case DISP_CHANGE_BADPARAM:
slouken@1895
   280
            reason = "DISP_CHANGE_BADPARAM";
slouken@1895
   281
            break;
slouken@1895
   282
        case DISP_CHANGE_FAILED:
slouken@1895
   283
            reason = "DISP_CHANGE_FAILED";
slouken@1895
   284
            break;
slouken@1895
   285
        }
slouken@1895
   286
        SDL_SetError("ChangeDisplaySettingsEx() failed: %s", reason);
slouken@1895
   287
        return -1;
slouken@1895
   288
    }
slouken@1895
   289
}
slouken@1895
   290
slouken@1895
   291
void
slouken@1895
   292
WIN_QuitModes(_THIS)
slouken@1895
   293
{
slouken@1895
   294
    ChangeDisplaySettingsEx(NULL, NULL, NULL, 0, NULL);
slouken@1895
   295
}
slouken@1895
   296
slouken@1895
   297
/* vi: set ts=4 sw=4 expandtab: */