src/video/win32/SDL_win32modes.c
author Edgar Simo <bobbens@gmail.com>
Sun, 06 Jul 2008 17:06:37 +0000
branchgsoc2008_force_feedback
changeset 2498 ab567bd667bf
parent 2149 eba4fd03b4f6
child 2859 99210400e8b9
permissions -rw-r--r--
Fixed various mistakes in the doxygen.
     1 /*
     2     SDL - Simple DirectMedia Layer
     3     Copyright (C) 1997-2006 Sam Lantinga
     4 
     5     This library is free software; you can redistribute it and/or
     6     modify it under the terms of the GNU Lesser General Public
     7     License as published by the Free Software Foundation; either
     8     version 2.1 of the License, or (at your option) any later version.
     9 
    10     This library is distributed in the hope that it will be useful,
    11     but WITHOUT ANY WARRANTY; without even the implied warranty of
    12     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    13     Lesser General Public License for more details.
    14 
    15     You should have received a copy of the GNU Lesser General Public
    16     License along with this library; if not, write to the Free Software
    17     Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
    18 
    19     Sam Lantinga
    20     slouken@libsdl.org
    21 */
    22 #include "SDL_config.h"
    23 
    24 #include "SDL_win32video.h"
    25 
    26 
    27 static SDL_bool
    28 WIN_GetDisplayMode(LPCTSTR deviceName, DWORD index, SDL_DisplayMode * mode)
    29 {
    30     SDL_DisplayModeData *data;
    31     DEVMODE devmode;
    32     HDC hdc;
    33 
    34     devmode.dmSize = sizeof(devmode);
    35     devmode.dmDriverExtra = 0;
    36     if (!EnumDisplaySettings(deviceName, index, &devmode)) {
    37         return SDL_FALSE;
    38     }
    39 
    40     data = (SDL_DisplayModeData *) SDL_malloc(sizeof(*data));
    41     if (!data) {
    42         return SDL_FALSE;
    43     }
    44     SDL_memcpy(data->DeviceName, deviceName, sizeof(data->DeviceName));
    45     data->DeviceMode = devmode;
    46     data->DeviceMode.dmFields =
    47         (DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT | DM_DISPLAYFREQUENCY |
    48          DM_DISPLAYFLAGS);
    49 
    50     /* Fill in the mode information */
    51     mode->format = SDL_PIXELFORMAT_UNKNOWN;
    52     mode->w = devmode.dmPelsWidth;
    53     mode->h = devmode.dmPelsHeight;
    54     mode->refresh_rate = devmode.dmDisplayFrequency;
    55     mode->driverdata = data;
    56 
    57     if (index == ENUM_CURRENT_SETTINGS
    58         && (hdc = CreateDC(deviceName, NULL, NULL, NULL)) != NULL) {
    59         char bmi_data[sizeof(BITMAPINFOHEADER) + 256 * sizeof(RGBQUAD)];
    60         LPBITMAPINFO bmi;
    61         HBITMAP hbm;
    62 
    63         SDL_zero(bmi_data);
    64         bmi = (LPBITMAPINFO) bmi_data;
    65         bmi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
    66 
    67         hbm = CreateCompatibleBitmap(hdc, 1, 1);
    68         GetDIBits(hdc, hbm, 0, 1, NULL, bmi, DIB_RGB_COLORS);
    69         GetDIBits(hdc, hbm, 0, 1, NULL, bmi, DIB_RGB_COLORS);
    70         DeleteObject(hbm);
    71         DeleteDC(hdc);
    72         if (bmi->bmiHeader.biCompression == BI_BITFIELDS) {
    73             switch (*(Uint32 *) bmi->bmiColors) {
    74             case 0x00FF0000:
    75                 mode->format = SDL_PIXELFORMAT_RGB888;
    76                 break;
    77             case 0x000000FF:
    78                 mode->format = SDL_PIXELFORMAT_BGR888;
    79                 break;
    80             case 0xF800:
    81                 mode->format = SDL_PIXELFORMAT_RGB565;
    82                 break;
    83             case 0x7C00:
    84                 mode->format = SDL_PIXELFORMAT_RGB555;
    85                 break;
    86             }
    87         } else if (bmi->bmiHeader.biBitCount == 8) {
    88             mode->format = SDL_PIXELFORMAT_INDEX8;
    89         }
    90     } else {
    91         /* FIXME: Can we tell what this will be? */
    92         switch (devmode.dmBitsPerPel) {
    93         case 32:
    94             mode->format = SDL_PIXELFORMAT_RGB888;
    95             break;
    96         case 24:
    97             mode->format = SDL_PIXELFORMAT_RGB24;
    98             break;
    99         case 16:
   100             mode->format = SDL_PIXELFORMAT_RGB565;
   101             break;
   102         case 15:
   103             mode->format = SDL_PIXELFORMAT_RGB555;
   104             break;
   105         case 8:
   106             mode->format = SDL_PIXELFORMAT_INDEX8;
   107             break;
   108         }
   109     }
   110     return SDL_TRUE;
   111 }
   112 
   113 static SDL_bool
   114 WIN_AddDisplay(LPTSTR DeviceName)
   115 {
   116     SDL_VideoDisplay display;
   117     SDL_DisplayData *displaydata;
   118     SDL_DisplayMode mode;
   119 
   120 #ifdef DEBUG_MODES
   121     printf("Display: %s\n", WIN_StringToUTF8(DeviceName));
   122 #endif
   123     if (!WIN_GetDisplayMode(DeviceName, ENUM_CURRENT_SETTINGS, &mode)) {
   124         return SDL_FALSE;
   125     }
   126 
   127     displaydata = (SDL_DisplayData *) SDL_malloc(sizeof(*displaydata));
   128     if (!displaydata) {
   129         return SDL_FALSE;
   130     }
   131     SDL_memcpy(displaydata->DeviceName, DeviceName,
   132                sizeof(displaydata->DeviceName));
   133 
   134     SDL_zero(display);
   135     display.desktop_mode = mode;
   136     display.current_mode = mode;
   137     display.driverdata = displaydata;
   138     SDL_AddVideoDisplay(&display);
   139     return SDL_TRUE;
   140 }
   141 
   142 void
   143 WIN_InitModes(_THIS)
   144 {
   145     SDL_VideoData *data = (SDL_VideoData *) _this->driverdata;
   146     DWORD i, j, count;
   147     DISPLAY_DEVICE device;
   148 
   149     device.cb = sizeof(device);
   150     for (i = 0;; ++i) {
   151         TCHAR DeviceName[32];
   152 
   153         if (!EnumDisplayDevices(NULL, i, &device, 0)) {
   154             break;
   155         }
   156         if (!(device.StateFlags & DISPLAY_DEVICE_ATTACHED_TO_DESKTOP)) {
   157             continue;
   158         }
   159         SDL_memcpy(DeviceName, device.DeviceName, sizeof(DeviceName));
   160 #ifdef DEBUG_MODES
   161         printf("Device: %s\n", WIN_StringToUTF8(DeviceName));
   162 #endif
   163         count = 0;
   164         for (j = 0;; ++j) {
   165             if (!EnumDisplayDevices(DeviceName, j, &device, 0)) {
   166                 break;
   167             }
   168             if (!(device.StateFlags & DISPLAY_DEVICE_ATTACHED_TO_DESKTOP)) {
   169                 continue;
   170             }
   171             count += WIN_AddDisplay(device.DeviceName);
   172         }
   173         if (count == 0) {
   174             WIN_AddDisplay(DeviceName);
   175         }
   176     }
   177 }
   178 
   179 void
   180 WIN_GetDisplayModes(_THIS)
   181 {
   182     SDL_DisplayData *data = (SDL_DisplayData *) SDL_CurrentDisplay.driverdata;
   183     DWORD i;
   184     SDL_DisplayMode mode;
   185 
   186     for (i = 0;; ++i) {
   187         if (!WIN_GetDisplayMode(data->DeviceName, i, &mode)) {
   188             break;
   189         }
   190         if (!SDL_AddDisplayMode(_this->current_display, &mode)) {
   191             SDL_free(mode.driverdata);
   192         }
   193     }
   194 }
   195 
   196 int
   197 WIN_SetDisplayMode(_THIS, SDL_DisplayMode * mode)
   198 {
   199     SDL_DisplayModeData *data = (SDL_DisplayModeData *) mode->driverdata;
   200     LONG status;
   201 
   202     status =
   203         ChangeDisplaySettingsEx(data->DeviceName, &data->DeviceMode, NULL,
   204                                 CDS_FULLSCREEN, NULL);
   205     if (status == DISP_CHANGE_SUCCESSFUL) {
   206         return 0;
   207     } else {
   208         const char *reason = "Unknown reason";
   209         switch (status) {
   210         case DISP_CHANGE_BADFLAGS:
   211             reason = "DISP_CHANGE_BADFLAGS";
   212             break;
   213         case DISP_CHANGE_BADMODE:
   214             reason = "DISP_CHANGE_BADMODE";
   215             break;
   216         case DISP_CHANGE_BADPARAM:
   217             reason = "DISP_CHANGE_BADPARAM";
   218             break;
   219         case DISP_CHANGE_FAILED:
   220             reason = "DISP_CHANGE_FAILED";
   221             break;
   222         }
   223         SDL_SetError("ChangeDisplaySettingsEx() failed: %s", reason);
   224         return -1;
   225     }
   226 }
   227 
   228 void
   229 WIN_QuitModes(_THIS)
   230 {
   231     ChangeDisplaySettingsEx(NULL, NULL, NULL, 0, NULL);
   232 }
   233 
   234 /* vi: set ts=4 sw=4 expandtab: */