Mercurial > sdl-ios-xcode
annotate EXCLUDE/GLIMM/src/Window.cpp @ 4745:0aaa54fbd2bc
Many changes, preparing to pull/merge main repo to get SDL_GetKeyboardFocus.
author | dewyatt |
---|---|
date | Tue, 06 Jul 2010 02:06:17 -0400 |
parents | 59b0750575b1 |
children |
rev | line source |
---|---|
4741 | 1 #include "Window.hpp" |
2 #include <gl/GL.h> | |
3 | |
4 #pragma comment(lib, "opengl32.lib") | |
5 | |
6 const wchar_t *Window::Window_Class_Name = L"GLTSF"; | |
7 | |
8 Window::Window() : my_Handle(0), | |
9 my_Device_Context(0), | |
10 my_GL_Context(0), | |
11 my_Class_Registered(false), | |
12 my_Listener(0) | |
13 { | |
14 | |
15 } | |
16 | |
17 Window::~Window() | |
18 { | |
19 Finalize(); | |
20 Show_Cursor(); | |
21 } | |
22 | |
23 void Window::Initialize(const std::wstring &Title, const Video_Mode &Mode, bool Fullscreen) | |
24 { | |
25 Finalize(); | |
26 | |
27 my_Video_Mode = Mode; | |
28 if (!my_Video_Mode.Is_Valid()) | |
29 throw std::runtime_error("Invalid video mode"); | |
30 | |
31 my_Fullscreen = Fullscreen; | |
32 Register_Class(); | |
33 Create_Window(Title, Mode, Fullscreen); | |
4745
0aaa54fbd2bc
Many changes, preparing to pull/merge main repo to get SDL_GetKeyboardFocus.
dewyatt
parents:
4742
diff
changeset
|
34 Show(); |
4741 | 35 my_IMM.Initialize(my_Handle); |
36 } | |
37 | |
38 void Window::Finalize() | |
39 { | |
40 my_IMM.Finalize(); | |
41 Destroy_Window(); | |
42 Unregister_Class(); | |
43 } | |
44 | |
45 void Window::Set_Listener(Window_Listener *Listener) | |
46 { | |
47 my_Listener = Listener; | |
48 } | |
49 | |
50 void Window::Show() | |
51 { | |
52 if (my_Handle) | |
53 ShowWindow(my_Handle, SW_SHOW); | |
54 } | |
55 | |
56 void Window::Hide() | |
57 { | |
58 if (my_Handle) | |
59 ShowWindow(my_Handle, SW_HIDE); | |
60 } | |
61 | |
62 void Window::Handle_Events() | |
63 { | |
64 MSG Message = {0}; | |
65 while (PeekMessageW(&Message, NULL, 0, 0, PM_REMOVE)) | |
66 { | |
67 TranslateMessage(&Message); | |
68 DispatchMessageW(&Message); | |
69 } | |
70 } | |
71 | |
72 void Window::Display() | |
73 { | |
74 if (my_Device_Context && my_GL_Context) | |
75 SwapBuffers(my_Device_Context); | |
76 } | |
77 | |
78 void Window::Show_Cursor() | |
79 { | |
80 ShowCursor(TRUE); | |
81 } | |
82 | |
83 void Window::Hide_Cursor() | |
84 { | |
85 ShowCursor(FALSE); | |
86 } | |
87 | |
88 HWND Window::Get_Handle() | |
89 { | |
90 return my_Handle; | |
91 } | |
92 | |
4742 | 93 IMM & Window::Get_IMM() |
94 { | |
95 return my_IMM; | |
96 } | |
97 | |
4741 | 98 void Window::Register_Class() |
99 { | |
100 WNDCLASSEXW Window_Class = {0}; | |
101 Window_Class.cbSize = sizeof(Window_Class); | |
102 Window_Class.style = 0; | |
103 Window_Class.lpfnWndProc = &Window::Window_Procedure; | |
104 Window_Class.cbClsExtra = 0; | |
105 Window_Class.cbWndExtra = 0; | |
106 Window_Class.hInstance = GetModuleHandle(NULL); | |
107 Window_Class.hIcon = NULL; | |
108 Window_Class.hCursor = NULL; | |
109 Window_Class.hbrBackground = NULL; | |
110 Window_Class.lpszMenuName = NULL; | |
111 Window_Class.lpszClassName = Window_Class_Name; | |
112 Window_Class.hIconSm = NULL; | |
113 if (0 == RegisterClassExW(&Window_Class)) | |
114 throw std::runtime_error("Failed to register window class"); | |
115 | |
116 my_Class_Registered = true; | |
117 } | |
118 | |
119 void Window::Unregister_Class() | |
120 { | |
121 if (my_Class_Registered) | |
122 { | |
123 if (0 == UnregisterClassW(Window_Class_Name, GetModuleHandle(NULL))) | |
124 printf("Warning: Failed to unregister window class\n"); | |
125 | |
126 my_Class_Registered = false; | |
127 } | |
128 } | |
129 | |
130 void Window::Create_Window(const std::wstring &Title, const Video_Mode &Mode, bool Fullscreen) | |
131 { | |
132 HDC Screen_DC = GetDC(NULL); | |
133 int Left = (GetDeviceCaps(Screen_DC, HORZRES) - my_Video_Mode.Width) / 2; | |
134 int Top = (GetDeviceCaps(Screen_DC, VERTRES) - my_Video_Mode.Height) / 2; | |
135 int Width = my_Video_Mode.Width; | |
136 int Height = my_Video_Mode.Height; | |
137 ReleaseDC(NULL, Screen_DC); | |
138 | |
139 DWORD Style = WS_CAPTION | WS_MINIMIZEBOX | WS_SYSMENU; | |
140 if (!my_Fullscreen) | |
141 { | |
142 RECT Rect = {0, 0, Width, Height}; | |
143 AdjustWindowRect(&Rect, Style, false); | |
144 Width = Rect.right - Rect.left; | |
145 Height = Rect.bottom - Rect.top; | |
146 } | |
147 my_Handle = CreateWindowW(Window_Class_Name, Title.c_str(), Style, Left, Top, Width, Height, NULL, NULL, GetModuleHandle(NULL), this); | |
148 if (!my_Handle) | |
149 throw std::runtime_error("Failed to create window"); | |
150 | |
151 if (Fullscreen) | |
152 Switch_To_Fullscreen(Mode); | |
153 | |
154 Create_Context(Mode); | |
155 | |
156 RECT Rect = {0}; | |
157 GetClientRect(my_Handle, &Rect); | |
158 //TODO: ... | |
159 } | |
160 | |
161 void Window::Destroy_Window() | |
162 { | |
163 Destroy_Context(); | |
164 if (my_Handle) | |
165 { | |
166 DestroyWindow(my_Handle); | |
167 my_Handle = 0; | |
168 | |
169 if (my_Fullscreen) | |
170 ChangeDisplaySettings(NULL, 0); | |
171 } | |
172 } | |
173 | |
174 void Window::Create_Context(const Video_Mode &Mode) | |
175 { | |
176 my_Device_Context = GetDC(my_Handle); | |
177 if (!my_Device_Context) | |
178 throw std::runtime_error("Failed to get device context"); | |
179 | |
180 PIXELFORMATDESCRIPTOR Pixel_Descriptor = {0}; | |
181 Pixel_Descriptor.nSize = sizeof(Pixel_Descriptor); | |
182 Pixel_Descriptor.nVersion = 1; | |
183 Pixel_Descriptor.iLayerType = PFD_MAIN_PLANE; | |
184 Pixel_Descriptor.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER; | |
185 Pixel_Descriptor.iPixelType = PFD_TYPE_RGBA; | |
186 Pixel_Descriptor.cColorBits = static_cast<BYTE>(Mode.Bits_Per_Pixel); | |
187 Pixel_Descriptor.cDepthBits = 24; | |
188 Pixel_Descriptor.cStencilBits = 8; | |
189 Pixel_Descriptor.cAlphaBits = Mode.Bits_Per_Pixel == 32 ? 8 : 0; | |
190 | |
191 int Best_Format = ChoosePixelFormat(my_Device_Context, &Pixel_Descriptor); | |
192 if (0 == Best_Format) | |
193 throw std::runtime_error("Failed to find suitable pixel format"); | |
194 | |
195 PIXELFORMATDESCRIPTOR Actual_Format = {0}; | |
196 Actual_Format.nSize = sizeof(Actual_Format); | |
197 Actual_Format.nVersion = 1; | |
198 DescribePixelFormat(my_Device_Context, Best_Format, sizeof(Actual_Format), &Actual_Format); | |
199 if (!SetPixelFormat(my_Device_Context, Best_Format, &Actual_Format)) | |
200 throw std::runtime_error("Failed to set device pixel format"); | |
201 | |
202 my_GL_Context = wglCreateContext(my_Device_Context); | |
203 if (!my_GL_Context) | |
204 throw std::runtime_error("Failed to create OpenGL context"); | |
205 | |
206 wglMakeCurrent(my_Device_Context, my_GL_Context); | |
207 } | |
208 | |
209 void Window::Destroy_Context() | |
210 { | |
211 if (my_GL_Context) | |
212 { | |
213 wglDeleteContext(my_GL_Context); | |
214 my_GL_Context = 0; | |
215 } | |
216 if (my_Device_Context) | |
217 { | |
218 ReleaseDC(my_Handle, my_Device_Context); | |
219 my_Device_Context = 0; | |
220 } | |
221 } | |
222 | |
223 void Window::Switch_To_Fullscreen(const Video_Mode &Mode) | |
224 { | |
225 DEVMODE Device_Mode = {0}; | |
226 Device_Mode.dmSize = sizeof(Device_Mode); | |
227 Device_Mode.dmPelsWidth = Mode.Width; | |
228 Device_Mode.dmPelsHeight = Mode.Height; | |
229 Device_Mode.dmBitsPerPel = Mode.Bits_Per_Pixel; | |
230 Device_Mode.dmFields = DM_PELSWIDTH | DM_PELSHEIGHT | DM_BITSPERPEL; | |
231 | |
232 if (DISP_CHANGE_SUCCESSFUL != ChangeDisplaySettings(&Device_Mode, CDS_FULLSCREEN)) | |
233 throw std::runtime_error("Failed to change to fullscreen mode"); | |
234 | |
235 SetWindowLong(my_Handle, GWL_STYLE, WS_POPUP | WS_CLIPCHILDREN | WS_CLIPSIBLINGS); | |
236 SetWindowLong(my_Handle, GWL_EXSTYLE, WS_EX_APPWINDOW); | |
237 | |
238 SetWindowPos(my_Handle, HWND_TOP, 0, 0, Mode.Width, Mode.Height, SWP_FRAMECHANGED); | |
239 } | |
240 | |
241 LRESULT CALLBACK Window::Window_Procedure(HWND Handle, UINT Message, WPARAM wParam, LPARAM lParam) | |
242 { | |
243 switch (Message) | |
244 { | |
245 case WM_CREATE: | |
246 { | |
247 LONG This = reinterpret_cast<LONG>(reinterpret_cast<CREATESTRUCT *>(lParam)->lpCreateParams); | |
248 SetWindowLongPtr(Handle, GWLP_USERDATA, This); | |
249 return 0; | |
250 } | |
251 break; | |
252 case WM_DESTROY: | |
253 PostQuitMessage(0); | |
254 return 0; | |
255 break; | |
256 default: | |
257 { | |
258 Window* Win = reinterpret_cast<Window *>(GetWindowLongPtr(Handle, GWLP_USERDATA)); | |
259 if (Win) | |
260 return Win->Handle_Message(Handle, Message, wParam, lParam); | |
261 } | |
262 break; | |
263 } | |
264 return DefWindowProcW(Handle, Message, wParam, lParam); | |
265 } | |
266 | |
267 #define Call_Listener(x)\ | |
268 if (my_Listener) my_Listener->x | |
269 | |
270 LRESULT Window::Handle_Message(HWND Handle, UINT Message, WPARAM wParam, LPARAM lParam) | |
271 { | |
272 bool IMM_Message = false; | |
273 LRESULT Result = my_IMM.Handle_Message(Handle, Message, wParam, lParam, IMM_Message); | |
274 if (IMM_Message) | |
275 return Result; | |
276 | |
277 switch (Message) | |
278 { | |
279 case WM_SIZE: | |
280 Call_Listener(On_Resized(LOWORD(lParam), HIWORD(lParam))); | |
281 break; | |
282 case WM_CLOSE: | |
283 Call_Listener(On_Close()); | |
284 break; | |
285 case WM_KEYDOWN: | |
286 Call_Listener(On_Key_Down(wParam)); | |
287 break; | |
288 case WM_KEYUP: | |
289 Call_Listener(On_Key_Up(wParam)); | |
290 break; | |
291 case WM_CHAR: | |
292 Call_Listener(On_Char(wParam)); | |
293 break; | |
4742 | 294 case WM_SETFOCUS: |
295 my_IMM.Focus_Gained(); | |
296 break; | |
297 case WM_KILLFOCUS: | |
298 my_IMM.Focus_Lost(); | |
299 break; | |
4745
0aaa54fbd2bc
Many changes, preparing to pull/merge main repo to get SDL_GetKeyboardFocus.
dewyatt
parents:
4742
diff
changeset
|
300 case WM_LBUTTONDOWN: |
0aaa54fbd2bc
Many changes, preparing to pull/merge main repo to get SDL_GetKeyboardFocus.
dewyatt
parents:
4742
diff
changeset
|
301 Call_Listener(On_Mouse_Button_Down(Mouse_Button_Left)); |
0aaa54fbd2bc
Many changes, preparing to pull/merge main repo to get SDL_GetKeyboardFocus.
dewyatt
parents:
4742
diff
changeset
|
302 break; |
0aaa54fbd2bc
Many changes, preparing to pull/merge main repo to get SDL_GetKeyboardFocus.
dewyatt
parents:
4742
diff
changeset
|
303 case WM_LBUTTONUP: |
0aaa54fbd2bc
Many changes, preparing to pull/merge main repo to get SDL_GetKeyboardFocus.
dewyatt
parents:
4742
diff
changeset
|
304 Call_Listener(On_Mouse_Button_Up(Mouse_Button_Left)); |
0aaa54fbd2bc
Many changes, preparing to pull/merge main repo to get SDL_GetKeyboardFocus.
dewyatt
parents:
4742
diff
changeset
|
305 break; |
0aaa54fbd2bc
Many changes, preparing to pull/merge main repo to get SDL_GetKeyboardFocus.
dewyatt
parents:
4742
diff
changeset
|
306 case WM_RBUTTONDOWN: |
0aaa54fbd2bc
Many changes, preparing to pull/merge main repo to get SDL_GetKeyboardFocus.
dewyatt
parents:
4742
diff
changeset
|
307 Call_Listener(On_Mouse_Button_Down(Mouse_Button_Right)); |
0aaa54fbd2bc
Many changes, preparing to pull/merge main repo to get SDL_GetKeyboardFocus.
dewyatt
parents:
4742
diff
changeset
|
308 break; |
0aaa54fbd2bc
Many changes, preparing to pull/merge main repo to get SDL_GetKeyboardFocus.
dewyatt
parents:
4742
diff
changeset
|
309 case WM_RBUTTONUP: |
0aaa54fbd2bc
Many changes, preparing to pull/merge main repo to get SDL_GetKeyboardFocus.
dewyatt
parents:
4742
diff
changeset
|
310 Call_Listener(On_Mouse_Button_Up(Mouse_Button_Right)); |
0aaa54fbd2bc
Many changes, preparing to pull/merge main repo to get SDL_GetKeyboardFocus.
dewyatt
parents:
4742
diff
changeset
|
311 break; |
4741 | 312 default: |
313 return DefWindowProcW(Handle, Message, wParam, lParam); | |
314 break; | |
315 } | |
316 return 0; | |
317 } |