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