src/video/win32/SDL_win32window.c
author Edgar Simo <bobbens@gmail.com>
Sun, 06 Jul 2008 17:06:37 +0000
branchgsoc2008_force_feedback
changeset 2498 ab567bd667bf
parent 1956 ba0d62354872
child 2580 64fa227c01ce
child 2710 44e49d3fa6cf
child 3767 abc8acb8e3d7
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_sysvideo.h"
    25 #include "../../events/SDL_keyboard_c.h"
    26 
    27 #include "SDL_win32video.h"
    28 
    29 /* This is included after SDL_win32video.h, which includes windows.h */
    30 #include "SDL_syswm.h"
    31 
    32 
    33 static int
    34 SetupWindowData(_THIS, SDL_Window * window, HWND hwnd, SDL_bool created)
    35 {
    36     SDL_VideoData *videodata = (SDL_VideoData *) _this->driverdata;
    37     SDL_WindowData *data;
    38 
    39     /* Allocate the window data */
    40     data = (SDL_WindowData *) SDL_malloc(sizeof(*data));
    41     if (!data) {
    42         SDL_OutOfMemory();
    43         return -1;
    44     }
    45     data->windowID = window->id;
    46     data->hwnd = hwnd;
    47     data->hdc = GetDC(hwnd);
    48     data->created = created;
    49     data->mouse_pressed = SDL_FALSE;
    50     data->videodata = videodata;
    51 
    52     /* Associate the data with the window */
    53     if (!SetProp(hwnd, TEXT("SDL_WindowData"), data)) {
    54         ReleaseDC(hwnd, data->hdc);
    55         SDL_free(data);
    56         WIN_SetError("SetProp() failed");
    57         return -1;
    58     }
    59 
    60     /* Set up the window proc function */
    61     data->wndproc = (WNDPROC) GetWindowLongPtr(hwnd, GWLP_WNDPROC);
    62     if (data->wndproc == NULL) {
    63         data->wndproc = DefWindowProc;
    64     } else {
    65         SetWindowLongPtr(hwnd, GWLP_WNDPROC, (LONG_PTR) WIN_WindowProc);
    66     }
    67 
    68     /* Fill in the SDL window with the window data */
    69     {
    70         POINT point;
    71         point.x = 0;
    72         point.y = 0;
    73         if (ClientToScreen(hwnd, &point)) {
    74             window->x = point.x;
    75             window->y = point.y;
    76         }
    77     }
    78     {
    79         RECT rect;
    80         if (GetClientRect(hwnd, &rect)) {
    81             window->w = rect.right;
    82             window->h = rect.bottom;
    83         }
    84     }
    85     {
    86         DWORD style = GetWindowLong(hwnd, GWL_STYLE);
    87         if (style & WS_VISIBLE) {
    88             window->flags |= SDL_WINDOW_SHOWN;
    89         } else {
    90             window->flags &= ~SDL_WINDOW_SHOWN;
    91         }
    92         if (style & (WS_BORDER | WS_THICKFRAME)) {
    93             window->flags &= ~SDL_WINDOW_BORDERLESS;
    94         } else {
    95             window->flags |= SDL_WINDOW_BORDERLESS;
    96         }
    97         if (style & WS_THICKFRAME) {
    98             window->flags |= SDL_WINDOW_RESIZABLE;
    99         } else {
   100             window->flags &= ~SDL_WINDOW_RESIZABLE;
   101         }
   102         if (style & WS_MAXIMIZE) {
   103             window->flags |= SDL_WINDOW_MAXIMIZED;
   104         } else {
   105             window->flags &= ~SDL_WINDOW_MAXIMIZED;
   106         }
   107         if (style & WS_MINIMIZE) {
   108             window->flags |= SDL_WINDOW_MINIMIZED;
   109         } else {
   110             window->flags &= ~SDL_WINDOW_MINIMIZED;
   111         }
   112     }
   113     if (GetFocus() == hwnd) {
   114         int index = data->videodata->keyboard;
   115         window->flags |= SDL_WINDOW_INPUT_FOCUS;
   116         SDL_SetKeyboardFocus(index, data->windowID);
   117 
   118         if (window->flags & SDL_WINDOW_INPUT_GRABBED) {
   119             RECT rect;
   120             GetClientRect(hwnd, &rect);
   121             ClientToScreen(hwnd, (LPPOINT) & rect);
   122             ClientToScreen(hwnd, (LPPOINT) & rect + 1);
   123             ClipCursor(&rect);
   124         }
   125     }
   126 
   127     /* All done! */
   128     window->driverdata = data;
   129     return 0;
   130 }
   131 
   132 int
   133 WIN_CreateWindow(_THIS, SDL_Window * window)
   134 {
   135     HWND hwnd;
   136     HWND top;
   137     RECT rect;
   138     DWORD style = (WS_CLIPSIBLINGS | WS_CLIPCHILDREN);
   139     int x, y;
   140     int w, h;
   141 
   142     if (window->flags & SDL_WINDOW_BORDERLESS) {
   143         style |= WS_POPUP;
   144     } else {
   145         style |= (WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX);
   146     }
   147     if (window->flags & SDL_WINDOW_RESIZABLE) {
   148         style |= (WS_THICKFRAME | WS_MAXIMIZEBOX);
   149     }
   150 
   151     /* Figure out what the window area will be */
   152     if (window->flags & SDL_WINDOW_FULLSCREEN) {
   153         top = HWND_TOPMOST;
   154     } else {
   155         top = HWND_NOTOPMOST;
   156     }
   157     rect.left = 0;
   158     rect.top = 0;
   159     rect.right = window->w;
   160     rect.bottom = window->h;
   161     AdjustWindowRectEx(&rect, style, FALSE, 0);
   162     w = (rect.right - rect.left);
   163     h = (rect.bottom - rect.top);
   164 
   165     if (window->x == SDL_WINDOWPOS_CENTERED) {
   166         x = (GetSystemMetrics(SM_CXSCREEN) - w) / 2;
   167     } else if (window->x == SDL_WINDOWPOS_UNDEFINED) {
   168         x = CW_USEDEFAULT;
   169     } else {
   170         x = window->x + rect.left;
   171     }
   172     if (window->y == SDL_WINDOWPOS_CENTERED) {
   173         y = (GetSystemMetrics(SM_CYSCREEN) - h) / 2;
   174     } else if (window->y == SDL_WINDOWPOS_UNDEFINED) {
   175         y = CW_USEDEFAULT;
   176     } else {
   177         y = window->y + rect.top;
   178     }
   179 
   180     hwnd =
   181         CreateWindow(SDL_Appname, TEXT(""), style, x, y, w, h, NULL, NULL,
   182                      SDL_Instance, NULL);
   183     WIN_PumpEvents(_this);
   184 
   185     if (!hwnd) {
   186         WIN_SetError("Couldn't create window");
   187         return -1;
   188     }
   189 
   190     if (SetupWindowData(_this, window, hwnd, SDL_TRUE) < 0) {
   191         DestroyWindow(hwnd);
   192         return -1;
   193     }
   194 #ifdef SDL_VIDEO_OPENGL_WGL
   195     if (window->flags & SDL_WINDOW_OPENGL) {
   196         if (WIN_GL_SetupWindow(_this, window) < 0) {
   197             WIN_DestroyWindow(_this, window);
   198             return -1;
   199         }
   200     }
   201 #endif
   202     return 0;
   203 }
   204 
   205 int
   206 WIN_CreateWindowFrom(_THIS, SDL_Window * window, const void *data)
   207 {
   208     HWND hwnd = (HWND) data;
   209     LPTSTR title;
   210     int titleLen;
   211 
   212     /* Query the title from the existing window */
   213     titleLen = GetWindowTextLength(hwnd);
   214     title = SDL_stack_alloc(TCHAR, titleLen + 1);
   215     if (title) {
   216         titleLen = GetWindowText(hwnd, title, titleLen);
   217     } else {
   218         titleLen = 0;
   219     }
   220     if (titleLen > 0) {
   221         window->title = WIN_StringToUTF8(title);
   222     }
   223     if (title) {
   224         SDL_stack_free(title);
   225     }
   226 
   227     if (SetupWindowData(_this, window, hwnd, SDL_FALSE) < 0) {
   228         return -1;
   229     }
   230     return 0;
   231 }
   232 
   233 void
   234 WIN_SetWindowTitle(_THIS, SDL_Window * window)
   235 {
   236     HWND hwnd = ((SDL_WindowData *) window->driverdata)->hwnd;
   237     LPTSTR title;
   238 
   239     if (window->title) {
   240         title = WIN_UTF8ToString(window->title);
   241     } else {
   242         title = NULL;
   243     }
   244     SetWindowText(hwnd, title ? title : TEXT(""));
   245     if (title) {
   246         SDL_free(title);
   247     }
   248 }
   249 
   250 void
   251 WIN_SetWindowPosition(_THIS, SDL_Window * window)
   252 {
   253     HWND hwnd = ((SDL_WindowData *) window->driverdata)->hwnd;
   254     RECT rect;
   255     DWORD style;
   256     HWND top;
   257     int x, y;
   258 
   259     /* Figure out what the window area will be */
   260     if (window->flags & SDL_WINDOW_FULLSCREEN) {
   261         top = HWND_TOPMOST;
   262     } else {
   263         top = HWND_NOTOPMOST;
   264     }
   265     style = GetWindowLong(hwnd, GWL_STYLE);
   266     rect.left = 0;
   267     rect.top = 0;
   268     rect.right = window->w;
   269     rect.bottom = window->h;
   270     AdjustWindowRectEx(&rect, style,
   271                        (style & WS_CHILDWINDOW) ? FALSE : (GetMenu(hwnd) !=
   272                                                            NULL), 0);
   273     x = window->x + rect.left;
   274     y = window->y + rect.top;
   275 
   276     SetWindowPos(hwnd, top, x, y, 0, 0, (SWP_NOCOPYBITS | SWP_NOSIZE));
   277 }
   278 
   279 void
   280 WIN_SetWindowSize(_THIS, SDL_Window * window)
   281 {
   282     HWND hwnd = ((SDL_WindowData *) window->driverdata)->hwnd;
   283     RECT rect;
   284     DWORD style;
   285     HWND top;
   286     int w, h;
   287 
   288     /* Figure out what the window area will be */
   289     if (window->flags & SDL_WINDOW_FULLSCREEN) {
   290         top = HWND_TOPMOST;
   291     } else {
   292         top = HWND_NOTOPMOST;
   293     }
   294     style = GetWindowLong(hwnd, GWL_STYLE);
   295     rect.left = 0;
   296     rect.top = 0;
   297     rect.right = window->w;
   298     rect.bottom = window->h;
   299     AdjustWindowRectEx(&rect, style,
   300                        (style & WS_CHILDWINDOW) ? FALSE : (GetMenu(hwnd) !=
   301                                                            NULL), 0);
   302     w = (rect.right - rect.left);
   303     h = (rect.bottom - rect.top);
   304 
   305     SetWindowPos(hwnd, top, 0, 0, h, w, (SWP_NOCOPYBITS | SWP_NOMOVE));
   306 }
   307 
   308 void
   309 WIN_ShowWindow(_THIS, SDL_Window * window)
   310 {
   311     HWND hwnd = ((SDL_WindowData *) window->driverdata)->hwnd;
   312 
   313     ShowWindow(hwnd, SW_SHOW);
   314 }
   315 
   316 void
   317 WIN_HideWindow(_THIS, SDL_Window * window)
   318 {
   319     HWND hwnd = ((SDL_WindowData *) window->driverdata)->hwnd;
   320 
   321     ShowWindow(hwnd, SW_HIDE);
   322 }
   323 
   324 void
   325 WIN_RaiseWindow(_THIS, SDL_Window * window)
   326 {
   327     HWND hwnd = ((SDL_WindowData *) window->driverdata)->hwnd;
   328     HWND top;
   329 
   330     if (window->flags & SDL_WINDOW_FULLSCREEN) {
   331         top = HWND_TOPMOST;
   332     } else {
   333         top = HWND_NOTOPMOST;
   334     }
   335     SetWindowPos(hwnd, top, 0, 0, 0, 0, (SWP_NOMOVE | SWP_NOSIZE));
   336 }
   337 
   338 void
   339 WIN_MaximizeWindow(_THIS, SDL_Window * window)
   340 {
   341     HWND hwnd = ((SDL_WindowData *) window->driverdata)->hwnd;
   342 
   343     ShowWindow(hwnd, SW_MAXIMIZE);
   344 }
   345 
   346 void
   347 WIN_MinimizeWindow(_THIS, SDL_Window * window)
   348 {
   349     HWND hwnd = ((SDL_WindowData *) window->driverdata)->hwnd;
   350 
   351     ShowWindow(hwnd, SW_MINIMIZE);
   352 }
   353 
   354 void
   355 WIN_RestoreWindow(_THIS, SDL_Window * window)
   356 {
   357     HWND hwnd = ((SDL_WindowData *) window->driverdata)->hwnd;
   358 
   359     ShowWindow(hwnd, SW_RESTORE);
   360 }
   361 
   362 void
   363 WIN_SetWindowGrab(_THIS, SDL_Window * window)
   364 {
   365     HWND hwnd = ((SDL_WindowData *) window->driverdata)->hwnd;
   366 
   367     if ((window->flags & SDL_WINDOW_INPUT_GRABBED) &&
   368         (window->flags & SDL_WINDOW_INPUT_FOCUS)) {
   369         RECT rect;
   370         GetClientRect(hwnd, &rect);
   371         ClientToScreen(hwnd, (LPPOINT) & rect);
   372         ClientToScreen(hwnd, (LPPOINT) & rect + 1);
   373         ClipCursor(&rect);
   374     } else {
   375         ClipCursor(NULL);
   376     }
   377 }
   378 
   379 void
   380 WIN_DestroyWindow(_THIS, SDL_Window * window)
   381 {
   382     SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
   383 
   384     if (data) {
   385 #ifdef SDL_VIDEO_OPENGL_WGL
   386         if (window->flags & SDL_WINDOW_OPENGL) {
   387             WIN_GL_CleanupWindow(_this, window);
   388         }
   389 #endif
   390         ReleaseDC(data->hwnd, data->hdc);
   391         if (data->created) {
   392             DestroyWindow(data->hwnd);
   393         }
   394         SDL_free(data);
   395     }
   396 }
   397 
   398 SDL_bool
   399 WIN_GetWindowWMInfo(_THIS, SDL_Window * window, SDL_SysWMinfo * info)
   400 {
   401     HWND hwnd = ((SDL_WindowData *) window->driverdata)->hwnd;
   402     if (info->version.major <= SDL_MAJOR_VERSION) {
   403         info->window = hwnd;
   404         return SDL_TRUE;
   405     } else {
   406         SDL_SetError("Application not compiled with SDL %d.%d\n",
   407                      SDL_MAJOR_VERSION, SDL_MINOR_VERSION);
   408         return SDL_FALSE;
   409     }
   410 }
   411 
   412 /* vi: set ts=4 sw=4 expandtab: */