Mercurial > sdl-ios-xcode
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: */ |