diff options
Diffstat (limited to '')
-rw-r--r-- | linden/indra/llwindow/llwindow.cpp | 420 |
1 files changed, 420 insertions, 0 deletions
diff --git a/linden/indra/llwindow/llwindow.cpp b/linden/indra/llwindow/llwindow.cpp new file mode 100644 index 0000000..20fc84e --- /dev/null +++ b/linden/indra/llwindow/llwindow.cpp | |||
@@ -0,0 +1,420 @@ | |||
1 | /** | ||
2 | * @file llwindow.cpp | ||
3 | * @brief Basic graphical window class | ||
4 | * | ||
5 | * Copyright (c) 2001-2007, Linden Research, Inc. | ||
6 | * | ||
7 | * The source code in this file ("Source Code") is provided by Linden Lab | ||
8 | * to you under the terms of the GNU General Public License, version 2.0 | ||
9 | * ("GPL"), unless you have obtained a separate licensing agreement | ||
10 | * ("Other License"), formally executed by you and Linden Lab. Terms of | ||
11 | * the GPL can be found in doc/GPL-license.txt in this distribution, or | ||
12 | * online at http://secondlife.com/developers/opensource/gplv2 | ||
13 | * | ||
14 | * There are special exceptions to the terms and conditions of the GPL as | ||
15 | * it is applied to this Source Code. View the full text of the exception | ||
16 | * in the file doc/FLOSS-exception.txt in this software distribution, or | ||
17 | * online at http://secondlife.com/developers/opensource/flossexception | ||
18 | * | ||
19 | * By copying, modifying or distributing this software, you acknowledge | ||
20 | * that you have read and understood your obligations described above, | ||
21 | * and agree to abide by those obligations. | ||
22 | * | ||
23 | * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO | ||
24 | * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, | ||
25 | * COMPLETENESS OR PERFORMANCE. | ||
26 | */ | ||
27 | |||
28 | #include "linden_common.h" | ||
29 | #include "llwindowheadless.h" | ||
30 | |||
31 | #if LL_MESA_HEADLESS | ||
32 | #include "llwindowmesaheadless.h" | ||
33 | #elif LL_SDL | ||
34 | #include "llwindowsdl.h" | ||
35 | #elif LL_WINDOWS | ||
36 | #include "llwindowwin32.h" | ||
37 | #elif LL_DARWIN | ||
38 | #include "llwindowmacosx.h" | ||
39 | #elif LL_LINUX | ||
40 | #include "llwindowlinux.h" // currently just a dummy wrapper | ||
41 | #endif | ||
42 | |||
43 | #include "llerror.h" | ||
44 | #include "llkeyboard.h" | ||
45 | #include "linked_lists.h" | ||
46 | |||
47 | //static instance for default callbacks | ||
48 | LLWindowCallbacks LLWindow::sDefaultCallbacks; | ||
49 | |||
50 | // | ||
51 | // LLWindowCallbacks | ||
52 | // | ||
53 | |||
54 | LLSplashScreen *gSplashScreenp = NULL; | ||
55 | BOOL gDebugClicks = FALSE; | ||
56 | BOOL gDebugWindowProc = FALSE; | ||
57 | |||
58 | const S32 gURLProtocolWhitelistCount = 3; | ||
59 | const char* gURLProtocolWhitelist[] = { "file", "http", "https" }; | ||
60 | |||
61 | // CP: added a handler list - this is what's used to open the protocol and is based on registry entry | ||
62 | // only meaningful difference currently is that file: protocols are opened using http: | ||
63 | // since no protocol handler exists in registry for file: | ||
64 | // Important - these lists should match - protocol to handler | ||
65 | const char* gURLProtocolWhitelistHandler[] = { "http", "http", "https" }; | ||
66 | |||
67 | BOOL LLWindowCallbacks::handleTranslatedKeyDown(const KEY key, const MASK mask, BOOL repeated) | ||
68 | { | ||
69 | return FALSE; | ||
70 | } | ||
71 | |||
72 | |||
73 | BOOL LLWindowCallbacks::handleTranslatedKeyUp(const KEY key, const MASK mask) | ||
74 | { | ||
75 | return FALSE; | ||
76 | } | ||
77 | |||
78 | void LLWindowCallbacks::handleScanKey(KEY key, BOOL key_down, BOOL key_up, BOOL key_level) | ||
79 | { | ||
80 | } | ||
81 | |||
82 | BOOL LLWindowCallbacks::handleUnicodeChar(llwchar uni_char, MASK mask) | ||
83 | { | ||
84 | return FALSE; | ||
85 | } | ||
86 | |||
87 | |||
88 | BOOL LLWindowCallbacks::handleMouseDown(LLWindow *window, const LLCoordGL pos, MASK mask) | ||
89 | { | ||
90 | return FALSE; | ||
91 | } | ||
92 | |||
93 | BOOL LLWindowCallbacks::handleMouseUp(LLWindow *window, const LLCoordGL pos, MASK mask) | ||
94 | { | ||
95 | return FALSE; | ||
96 | } | ||
97 | |||
98 | void LLWindowCallbacks::handleMouseLeave(LLWindow *window) | ||
99 | { | ||
100 | return; | ||
101 | } | ||
102 | |||
103 | BOOL LLWindowCallbacks::handleCloseRequest(LLWindow *window) | ||
104 | { | ||
105 | //allow the window to close | ||
106 | return TRUE; | ||
107 | } | ||
108 | |||
109 | void LLWindowCallbacks::handleQuit(LLWindow *window) | ||
110 | { | ||
111 | if(LLWindowManager::destroyWindow(window) == FALSE) | ||
112 | { | ||
113 | llerrs << "LLWindowCallbacks::handleQuit() : Couldn't destroy window" << llendl; | ||
114 | } | ||
115 | } | ||
116 | |||
117 | BOOL LLWindowCallbacks::handleRightMouseDown(LLWindow *window, const LLCoordGL pos, MASK mask) | ||
118 | { | ||
119 | return FALSE; | ||
120 | } | ||
121 | |||
122 | BOOL LLWindowCallbacks::handleRightMouseUp(LLWindow *window, const LLCoordGL pos, MASK mask) | ||
123 | { | ||
124 | return FALSE; | ||
125 | } | ||
126 | |||
127 | BOOL LLWindowCallbacks::handleActivate(LLWindow *window, BOOL activated) | ||
128 | { | ||
129 | return FALSE; | ||
130 | } | ||
131 | |||
132 | void LLWindowCallbacks::handleMouseMove(LLWindow *window, const LLCoordGL pos, MASK mask) | ||
133 | { | ||
134 | } | ||
135 | |||
136 | void LLWindowCallbacks::handleScrollWheel(LLWindow *window, S32 clicks) | ||
137 | { | ||
138 | } | ||
139 | |||
140 | void LLWindowCallbacks::handleResize(LLWindow *window, const S32 width, const S32 height) | ||
141 | { | ||
142 | } | ||
143 | |||
144 | void LLWindowCallbacks::handleFocus(LLWindow *window) | ||
145 | { | ||
146 | } | ||
147 | |||
148 | void LLWindowCallbacks::handleFocusLost(LLWindow *window) | ||
149 | { | ||
150 | } | ||
151 | |||
152 | void LLWindowCallbacks::handleMenuSelect(LLWindow *window, const S32 menu_item) | ||
153 | { | ||
154 | } | ||
155 | |||
156 | BOOL LLWindowCallbacks::handlePaint(LLWindow *window, const S32 x, const S32 y, | ||
157 | const S32 width, const S32 height) | ||
158 | { | ||
159 | return FALSE; | ||
160 | } | ||
161 | |||
162 | BOOL LLWindowCallbacks::handleDoubleClick(LLWindow *window, const LLCoordGL pos, MASK mask) | ||
163 | { | ||
164 | return FALSE; | ||
165 | } | ||
166 | |||
167 | void LLWindowCallbacks::handleWindowBlock(LLWindow *window) | ||
168 | { | ||
169 | } | ||
170 | |||
171 | void LLWindowCallbacks::handleWindowUnblock(LLWindow *window) | ||
172 | { | ||
173 | } | ||
174 | |||
175 | void LLWindowCallbacks::handleDataCopy(LLWindow *window, S32 data_type, void *data) | ||
176 | { | ||
177 | } | ||
178 | |||
179 | |||
180 | S32 OSMessageBox(const char* text, const char* caption, U32 type) | ||
181 | { | ||
182 | // Properly hide the splash screen when displaying the message box | ||
183 | BOOL was_visible = FALSE; | ||
184 | if (LLSplashScreen::isVisible()) | ||
185 | { | ||
186 | was_visible = TRUE; | ||
187 | LLSplashScreen::hide(); | ||
188 | } | ||
189 | |||
190 | S32 result = 0; | ||
191 | #if LL_MESA_HEADLESS // !!! *FIX: (???) | ||
192 | llwarns << "OSMessageBox: " << text << llendl; | ||
193 | return OSBTN_OK; | ||
194 | #elif LL_WINDOWS | ||
195 | result = OSMessageBoxWin32(text, caption, type); | ||
196 | #elif LL_DARWIN | ||
197 | result = OSMessageBoxMacOSX(text, caption, type); | ||
198 | #elif LL_SDL | ||
199 | result = OSMessageBoxSDL(text, caption, type); | ||
200 | #else | ||
201 | #error("OSMessageBox not implemented for this platform!") | ||
202 | #endif | ||
203 | |||
204 | if (was_visible) | ||
205 | { | ||
206 | LLSplashScreen::show(); | ||
207 | } | ||
208 | |||
209 | return result; | ||
210 | } | ||
211 | |||
212 | |||
213 | // | ||
214 | // LLWindow | ||
215 | // | ||
216 | |||
217 | LLWindow::LLWindow(BOOL fullscreen, U32 flags) | ||
218 | : mCallbacks(&sDefaultCallbacks), | ||
219 | mPostQuit(TRUE), | ||
220 | mFullscreen(fullscreen), | ||
221 | mFullscreenWidth(0), | ||
222 | mFullscreenHeight(0), | ||
223 | mFullscreenBits(0), | ||
224 | mFullscreenRefresh(0), | ||
225 | mSupportedResolutions(NULL), | ||
226 | mNumSupportedResolutions(0), | ||
227 | mCurrentCursor(UI_CURSOR_ARROW), | ||
228 | mCursorHidden(FALSE), | ||
229 | mBusyCount(0), | ||
230 | mIsMouseClipping(FALSE), | ||
231 | mSwapMethod(SWAP_METHOD_UNDEFINED), | ||
232 | mHideCursorPermanent(FALSE), | ||
233 | mFlags(flags) | ||
234 | { | ||
235 | } | ||
236 | |||
237 | // virtual | ||
238 | void LLWindow::incBusyCount() | ||
239 | { | ||
240 | ++mBusyCount; | ||
241 | } | ||
242 | |||
243 | // virtual | ||
244 | void LLWindow::decBusyCount() | ||
245 | { | ||
246 | if (mBusyCount > 0) | ||
247 | { | ||
248 | --mBusyCount; | ||
249 | } | ||
250 | } | ||
251 | |||
252 | void LLWindow::setCallbacks(LLWindowCallbacks *callbacks) | ||
253 | { | ||
254 | mCallbacks = callbacks; | ||
255 | if (gKeyboard) | ||
256 | { | ||
257 | gKeyboard->setCallbacks(callbacks); | ||
258 | } | ||
259 | } | ||
260 | |||
261 | // | ||
262 | // LLSplashScreen | ||
263 | // | ||
264 | |||
265 | // static | ||
266 | bool LLSplashScreen::isVisible() | ||
267 | { | ||
268 | return gSplashScreenp ? true: false; | ||
269 | } | ||
270 | |||
271 | // static | ||
272 | LLSplashScreen *LLSplashScreen::create() | ||
273 | { | ||
274 | #if LL_MESA_HEADLESS || LL_SDL // !!! *FIX: (???) | ||
275 | return 0; | ||
276 | #elif LL_WINDOWS | ||
277 | return new LLSplashScreenWin32; | ||
278 | #elif LL_DARWIN | ||
279 | return new LLSplashScreenMacOSX; | ||
280 | #else | ||
281 | #error("LLSplashScreen not implemented on this platform!") | ||
282 | #endif | ||
283 | } | ||
284 | |||
285 | |||
286 | //static | ||
287 | void LLSplashScreen::show() | ||
288 | { | ||
289 | if (!gSplashScreenp) | ||
290 | { | ||
291 | #if LL_WINDOWS && !LL_MESA_HEADLESS | ||
292 | gSplashScreenp = new LLSplashScreenWin32; | ||
293 | #elif LL_DARWIN | ||
294 | gSplashScreenp = new LLSplashScreenMacOSX; | ||
295 | #endif | ||
296 | if (gSplashScreenp) | ||
297 | { | ||
298 | gSplashScreenp->showImpl(); | ||
299 | } | ||
300 | } | ||
301 | } | ||
302 | |||
303 | //static | ||
304 | void LLSplashScreen::update(const char* str) | ||
305 | { | ||
306 | LLSplashScreen::show(); | ||
307 | if (gSplashScreenp) | ||
308 | { | ||
309 | gSplashScreenp->updateImpl(str); | ||
310 | } | ||
311 | } | ||
312 | |||
313 | //static | ||
314 | void LLSplashScreen::hide() | ||
315 | { | ||
316 | if (gSplashScreenp) | ||
317 | { | ||
318 | gSplashScreenp->hideImpl(); | ||
319 | } | ||
320 | delete gSplashScreenp; | ||
321 | gSplashScreenp = NULL; | ||
322 | } | ||
323 | |||
324 | // | ||
325 | // LLWindowManager | ||
326 | // | ||
327 | |||
328 | // TODO: replace with std::set | ||
329 | static LLLinkedList<LLWindow> sWindowList; | ||
330 | |||
331 | LLWindow* LLWindowManager::createWindow( | ||
332 | char *title, | ||
333 | char *name, | ||
334 | LLCoordScreen upper_left, | ||
335 | LLCoordScreen size, | ||
336 | U32 flags, | ||
337 | BOOL fullscreen, | ||
338 | BOOL clearBg, | ||
339 | BOOL disable_vsync, | ||
340 | BOOL use_gl, | ||
341 | BOOL ignore_pixel_depth) | ||
342 | { | ||
343 | return createWindow( | ||
344 | title, name, upper_left.mX, upper_left.mY, size.mX, size.mY, flags, | ||
345 | fullscreen, clearBg, disable_vsync, use_gl, ignore_pixel_depth); | ||
346 | } | ||
347 | |||
348 | LLWindow* LLWindowManager::createWindow( | ||
349 | char *title, char *name, S32 x, S32 y, S32 width, S32 height, U32 flags, | ||
350 | BOOL fullscreen, | ||
351 | BOOL clearBg, | ||
352 | BOOL disable_vsync, | ||
353 | BOOL use_gl, | ||
354 | BOOL ignore_pixel_depth) | ||
355 | { | ||
356 | LLWindow* new_window; | ||
357 | |||
358 | if (use_gl) | ||
359 | { | ||
360 | #if LL_MESA_HEADLESS | ||
361 | new_window = new LLWindowMesaHeadless( | ||
362 | title, name, x, y, width, height, flags, | ||
363 | fullscreen, clearBg, disable_vsync, use_gl, ignore_pixel_depth); | ||
364 | #elif LL_SDL | ||
365 | new_window = new LLWindowSDL( | ||
366 | title, x, y, width, height, flags, | ||
367 | fullscreen, clearBg, disable_vsync, use_gl, ignore_pixel_depth); | ||
368 | #elif LL_WINDOWS | ||
369 | new_window = new LLWindowWin32( | ||
370 | title, name, x, y, width, height, flags, | ||
371 | fullscreen, clearBg, disable_vsync, use_gl, ignore_pixel_depth); | ||
372 | #elif LL_DARWIN | ||
373 | new_window = new LLWindowMacOSX( | ||
374 | title, name, x, y, width, height, flags, | ||
375 | fullscreen, clearBg, disable_vsync, use_gl, ignore_pixel_depth); | ||
376 | #elif LL_LINUX | ||
377 | new_window = new LLWindowLinux( | ||
378 | title, name, x, y, width, height, flags, | ||
379 | fullscreen, clearBg, disable_vsync, use_gl, ignore_pixel_depth); | ||
380 | #endif | ||
381 | } | ||
382 | else | ||
383 | { | ||
384 | new_window = new LLWindowHeadless( | ||
385 | title, name, x, y, width, height, flags, | ||
386 | fullscreen, clearBg, disable_vsync, use_gl, ignore_pixel_depth); | ||
387 | } | ||
388 | |||
389 | if (FALSE == new_window->isValid()) | ||
390 | { | ||
391 | delete new_window; | ||
392 | llwarns << "LLWindowManager::create() : Error creating window." << llendl; | ||
393 | return NULL; | ||
394 | } | ||
395 | sWindowList.addDataAtEnd(new_window); | ||
396 | return new_window; | ||
397 | } | ||
398 | |||
399 | BOOL LLWindowManager::destroyWindow(LLWindow* window) | ||
400 | { | ||
401 | if (!sWindowList.checkData(window)) | ||
402 | { | ||
403 | llerrs << "LLWindowManager::destroyWindow() : Window pointer not valid, this window doesn't exist!" | ||
404 | << llendl; | ||
405 | return FALSE; | ||
406 | } | ||
407 | |||
408 | window->close(); | ||
409 | |||
410 | sWindowList.removeData(window); | ||
411 | |||
412 | delete window; | ||
413 | |||
414 | return TRUE; | ||
415 | } | ||
416 | |||
417 | BOOL LLWindowManager::isWindowValid(LLWindow *window) | ||
418 | { | ||
419 | return sWindowList.checkData(window); | ||
420 | } | ||