Mercurial > sdl-ios-xcode
diff src/video/win32/SDL_win32window.c @ 1895:c121d94672cb
SDL 1.2 is moving to a branch, and SDL 1.3 is becoming the head.
author | Sam Lantinga <slouken@libsdl.org> |
---|---|
date | Mon, 10 Jul 2006 21:04:37 +0000 |
parents | |
children | 83420da906a5 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/video/win32/SDL_win32window.c Mon Jul 10 21:04:37 2006 +0000 @@ -0,0 +1,434 @@ +/* + SDL - Simple DirectMedia Layer + Copyright (C) 1997-2006 Sam Lantinga + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + + Sam Lantinga + slouken@libsdl.org +*/ +#include "SDL_config.h" + +#include "../SDL_sysvideo.h" +#include "../../events/SDL_keyboard_c.h" + +#include "SDL_win32video.h" + +/* This is included after SDL_win32video.h, which includes windows.h */ +#include "SDL_syswm.h" + + +static int +SetupWindowData(SDL_Window * window, HWND hwnd, BOOL created) +{ + SDL_WindowData *data; + + /* Allocate the window data */ + data = (SDL_WindowData *) SDL_malloc(sizeof(*data)); + if (!data) { + SDL_OutOfMemory(); + return -1; + } + data->windowID = window->id; + data->hwnd = hwnd; + data->created = created; + data->mouse_pressed = SDL_FALSE; + data->videodata = (SDL_VideoData *) SDL_GetVideoDevice()->driverdata; + + /* Associate the data with the window */ + if (!SetProp(hwnd, TEXT("SDL_WindowData"), data)) { + SDL_free(data); + WIN_SetError("SetProp() failed"); + return -1; + } + + /* Set up the window proc function */ + data->wndproc = (WNDPROC) GetWindowLongPtr(hwnd, GWLP_WNDPROC); + if (data->wndproc == NULL) { + data->wndproc = DefWindowProc; + } else { + SetWindowLongPtr(hwnd, GWLP_WNDPROC, (LONG_PTR) WIN_WindowProc); + } + + /* Fill in the SDL window with the window data */ + { + POINT point; + point.x = 0; + point.y = 0; + if (ClientToScreen(hwnd, &point)) { + window->x = point.x; + window->y = point.y; + } + } + { + RECT rect; + if (GetClientRect(hwnd, &rect)) { + window->w = rect.right; + window->h = rect.bottom; + } + } + { + DWORD style = GetWindowLong(hwnd, GWL_STYLE); + if (style & WS_VISIBLE) { + window->flags |= SDL_WINDOW_SHOWN; + } else { + window->flags &= ~SDL_WINDOW_SHOWN; + } + if (style & (WS_BORDER | WS_THICKFRAME)) { + window->flags &= ~SDL_WINDOW_BORDERLESS; + } else { + window->flags |= SDL_WINDOW_BORDERLESS; + } + if (style & WS_THICKFRAME) { + window->flags |= SDL_WINDOW_RESIZABLE; + } else { + window->flags &= ~SDL_WINDOW_RESIZABLE; + } + if (style & WS_MAXIMIZE) { + window->flags |= SDL_WINDOW_MAXIMIZED; + } else { + window->flags &= ~SDL_WINDOW_MAXIMIZED; + } + if (style & WS_MINIMIZE) { + window->flags |= SDL_WINDOW_MINIMIZED; + } else { + window->flags &= ~SDL_WINDOW_MINIMIZED; + } + } + if (GetFocus() == hwnd) { + int index = data->videodata->keyboard; + window->flags |= SDL_WINDOW_INPUT_FOCUS; + SDL_SetKeyboardFocus(index, data->windowID); + + if (window->flags & SDL_WINDOW_INPUT_GRABBED) { + RECT rect; + GetClientRect(hwnd, &rect); + ClientToScreen(hwnd, (LPPOINT) & rect); + ClientToScreen(hwnd, (LPPOINT) & rect + 1); + ClipCursor(&rect); + } + } + + /* All done! */ + window->driverdata = data; + return 0; +} + +int +WIN_CreateWindow(_THIS, SDL_Window * window) +{ + HWND hwnd; + LPTSTR title = NULL; + HWND top; + RECT rect; + DWORD style = 0; + int x, y; + int w, h; + + if (window->title) { + title = WIN_UTF8ToString(window->title); + } else { + title = NULL; + } + + if (window->flags & SDL_WINDOW_SHOWN) { + style |= WS_VISIBLE; + } + if ((window->flags & (SDL_WINDOW_FULLSCREEN | SDL_WINDOW_BORDERLESS))) { + style |= WS_POPUP; + } else { + style |= (WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX); + } + if (window->flags & SDL_WINDOW_RESIZABLE) { + style |= (WS_THICKFRAME | WS_MAXIMIZEBOX); + } + if (window->flags & SDL_WINDOW_MAXIMIZED) { + style |= WS_MAXIMIZE; + } + if (window->flags & SDL_WINDOW_MINIMIZED) { + style |= WS_MINIMIZE; + } + + /* Figure out what the window area will be */ + if (window->flags & SDL_WINDOW_FULLSCREEN) { + top = HWND_TOPMOST; + } else { + top = HWND_NOTOPMOST; + } + rect.left = 0; + rect.top = 0; + rect.right = window->w; + rect.bottom = window->h; + AdjustWindowRectEx(&rect, style, FALSE, 0); + w = (rect.right - rect.left); + h = (rect.bottom - rect.top); + + if ((window->flags & SDL_WINDOW_FULLSCREEN) || + window->x == SDL_WINDOWPOS_CENTERED) { + x = (GetSystemMetrics(SM_CXSCREEN) - w) / 2; + } else if (window->x == SDL_WINDOWPOS_UNDEFINED) { + x = CW_USEDEFAULT; + } else { + x = window->x + rect.left; + } + if ((window->flags & SDL_WINDOW_FULLSCREEN) || + window->y == SDL_WINDOWPOS_CENTERED) { + y = (GetSystemMetrics(SM_CYSCREEN) - h) / 2; + } else if (window->y == SDL_WINDOWPOS_UNDEFINED) { + y = CW_USEDEFAULT; + } else { + y = window->y + rect.top; + } + + hwnd = CreateWindow(SDL_Appname, + title ? title : TEXT(""), + style, x, y, w, h, NULL, NULL, SDL_Instance, NULL); + WIN_PumpEvents(_this); + + if (title) { + SDL_free(title); + } + + if (!hwnd) { + WIN_SetError("Couldn't create window"); + return -1; + } + + if (SetupWindowData(window, hwnd, TRUE) < 0) { + DestroyWindow(hwnd); + return -1; + } + return 0; +} + +int +WIN_CreateWindowFrom(_THIS, SDL_Window * window, const void *data) +{ + HWND hwnd = (HWND) data; + LPTSTR title; + int titleLen; + + /* Query the title from the existing window */ + titleLen = GetWindowTextLength(hwnd); + title = SDL_stack_alloc(TCHAR, titleLen + 1); + if (title) { + titleLen = GetWindowText(hwnd, title, titleLen); + } else { + titleLen = 0; + } + if (titleLen > 0) { + window->title = WIN_StringToUTF8(title); + } + if (title) { + SDL_stack_free(title); + } + + if (SetupWindowData(window, hwnd, FALSE) < 0) { + return -1; + } + return 0; +} + +void +WIN_SetWindowTitle(_THIS, SDL_Window * window) +{ + HWND hwnd = ((SDL_WindowData *) window->driverdata)->hwnd; + LPTSTR title; + + if (window->title) { + title = WIN_UTF8ToString(window->title); + } else { + title = NULL; + } + SetWindowText(hwnd, title ? title : TEXT("")); + if (title) { + SDL_free(title); + } +} + +void +WIN_SetWindowPosition(_THIS, SDL_Window * window) +{ + HWND hwnd = ((SDL_WindowData *) window->driverdata)->hwnd; + RECT rect; + DWORD style; + HWND top; + int x, y; + int w, h; + + /* Figure out what the window area will be */ + if (window->flags & SDL_WINDOW_FULLSCREEN) { + top = HWND_TOPMOST; + } else { + top = HWND_NOTOPMOST; + } + style = GetWindowLong(hwnd, GWL_STYLE); + rect.left = 0; + rect.top = 0; + rect.right = window->w; + rect.bottom = window->h; + AdjustWindowRectEx(&rect, style, + (style & WS_CHILDWINDOW) ? FALSE : (GetMenu(hwnd) != + NULL), 0); + w = (rect.right - rect.left); + h = (rect.bottom - rect.top); + + if ((window->flags & SDL_WINDOW_FULLSCREEN) || + window->x == SDL_WINDOWPOS_CENTERED) { + x = (GetSystemMetrics(SM_CXSCREEN) - w) / 2; + window->x = x - rect.left; + } else { + x = window->x + rect.left; + } + if ((window->flags & SDL_WINDOW_FULLSCREEN) || + window->y == SDL_WINDOWPOS_CENTERED) { + y = (GetSystemMetrics(SM_CYSCREEN) - h) / 2; + window->y = y - rect.top; + } else { + y = window->y + rect.top; + } + SetWindowPos(hwnd, top, x, y, h, w, (SWP_NOCOPYBITS | SWP_NOSIZE)); +} + +void +WIN_SetWindowSize(_THIS, SDL_Window * window) +{ + HWND hwnd = ((SDL_WindowData *) window->driverdata)->hwnd; + RECT rect; + DWORD style; + HWND top; + int w, h; + + /* Figure out what the window area will be */ + if (window->flags & SDL_WINDOW_FULLSCREEN) { + top = HWND_TOPMOST; + } else { + top = HWND_NOTOPMOST; + } + style = GetWindowLong(hwnd, GWL_STYLE); + rect.left = 0; + rect.top = 0; + rect.right = window->w; + rect.bottom = window->h; + AdjustWindowRectEx(&rect, style, + (style & WS_CHILDWINDOW) ? FALSE : (GetMenu(hwnd) != + NULL), 0); + w = (rect.right - rect.left); + h = (rect.bottom - rect.top); + + SetWindowPos(hwnd, top, 0, 0, h, w, (SWP_NOCOPYBITS | SWP_NOMOVE)); +} + +void +WIN_ShowWindow(_THIS, SDL_Window * window) +{ + HWND hwnd = ((SDL_WindowData *) window->driverdata)->hwnd; + + ShowWindow(hwnd, SW_SHOW); +} + +void +WIN_HideWindow(_THIS, SDL_Window * window) +{ + HWND hwnd = ((SDL_WindowData *) window->driverdata)->hwnd; + + ShowWindow(hwnd, SW_HIDE); +} + +void +WIN_RaiseWindow(_THIS, SDL_Window * window) +{ + HWND hwnd = ((SDL_WindowData *) window->driverdata)->hwnd; + HWND top; + + if (window->flags & SDL_WINDOW_FULLSCREEN) { + top = HWND_TOPMOST; + } else { + top = HWND_NOTOPMOST; + } + SetWindowPos(hwnd, top, 0, 0, 0, 0, (SWP_NOMOVE | SWP_NOSIZE)); +} + +void +WIN_MaximizeWindow(_THIS, SDL_Window * window) +{ + HWND hwnd = ((SDL_WindowData *) window->driverdata)->hwnd; + + ShowWindow(hwnd, SW_MAXIMIZE); +} + +void +WIN_MinimizeWindow(_THIS, SDL_Window * window) +{ + HWND hwnd = ((SDL_WindowData *) window->driverdata)->hwnd; + + ShowWindow(hwnd, SW_MINIMIZE); +} + +void +WIN_RestoreWindow(_THIS, SDL_Window * window) +{ + HWND hwnd = ((SDL_WindowData *) window->driverdata)->hwnd; + + ShowWindow(hwnd, SW_RESTORE); +} + +void +WIN_SetWindowGrab(_THIS, SDL_Window * window) +{ + HWND hwnd = ((SDL_WindowData *) window->driverdata)->hwnd; + + if ((window->flags & SDL_WINDOW_INPUT_GRABBED) && + (window->flags & SDL_WINDOW_INPUT_FOCUS)) { + RECT rect; + GetClientRect(hwnd, &rect); + ClientToScreen(hwnd, (LPPOINT) & rect); + ClientToScreen(hwnd, (LPPOINT) & rect + 1); + ClipCursor(&rect); + } else { + ClipCursor(NULL); + } +} + +void +WIN_DestroyWindow(_THIS, SDL_Window * window) +{ + SDL_WindowData *data = (SDL_WindowData *) window->driverdata; + + if (data) { + if (data->created) { + DestroyWindow(data->hwnd); + } + SDL_free(data); + } +} + +SDL_bool +WIN_GetWindowWMInfo(_THIS, SDL_Window * window, SDL_SysWMinfo * info) +{ + HWND hwnd = ((SDL_WindowData *) window->driverdata)->hwnd; + if (info->version.major <= SDL_MAJOR_VERSION) { + info->window = hwnd; + /* FIXME! */ + info->hglrc = NULL; + return SDL_TRUE; + } else { + SDL_SetError("Application not compiled with SDL %d.%d\n", + SDL_MAJOR_VERSION, SDL_MINOR_VERSION); + return SDL_FALSE; + } +} + +/* vi: set ts=4 sw=4 expandtab: */