00001
00032 #include "llviewerprecompiledheaders.h"
00033
00034 #include "llpanellogin.h"
00035 #include "llviewerkeyboard.h"
00036 #include "llviewerwindow.h"
00037
00038
00039 #include <stdio.h>
00040 #include <iostream>
00041 #include <fstream>
00042
00043 #include "llviewquery.h"
00044 #include "llxmltree.h"
00045
00046 #include "llglimmediate.h"
00047
00048 #include "llvoiceclient.h"
00049
00050 #ifdef SABINRIG
00051 #include "cbw.h"
00052 #endif //SABINRIG
00053
00054
00055
00056
00057
00058
00059 #include "audioengine.h"
00060 #include "indra_constants.h"
00061 #include "llassetstorage.h"
00062 #include "llfontgl.h"
00063 #include "llrect.h"
00064 #include "llsky.h"
00065 #include "llstring.h"
00066 #include "llui.h"
00067 #include "lluuid.h"
00068 #include "llview.h"
00069 #include "llxfermanager.h"
00070 #include "message.h"
00071 #include "object_flags.h"
00072 #include "lltimer.h"
00073 #include "timing.h"
00074 #include "llviewermenu.h"
00075
00076
00077 #include "llagent.h"
00078 #include "llalertdialog.h"
00079 #include "llbox.h"
00080 #include "llchatbar.h"
00081 #include "llconsole.h"
00082 #include "llviewercontrol.h"
00083 #include "llcylinder.h"
00084 #include "lldebugview.h"
00085 #include "lldir.h"
00086 #include "lldrawable.h"
00087 #include "lldrawpoolalpha.h"
00088 #include "lldrawpoolbump.h"
00089 #include "lldrawpoolwater.h"
00090 #include "llmaniptranslate.h"
00091 #include "llface.h"
00092 #include "llfeaturemanager.h"
00093 #include "llfilepicker.h"
00094 #include "llfloater.h"
00095 #include "llfloateractivespeakers.h"
00096 #include "llfloaterbuildoptions.h"
00097 #include "llfloaterbuyland.h"
00098 #include "llfloatercamera.h"
00099 #include "llfloaterchat.h"
00100 #include "llfloaterchatterbox.h"
00101 #include "llfloatercustomize.h"
00102 #include "llfloatereditui.h"
00103 #include "llfloaterland.h"
00104 #include "llfloaterinspect.h"
00105 #include "llfloatermap.h"
00106 #include "llfloaternamedesc.h"
00107 #include "llfloaterpreference.h"
00108 #include "llfloatersnapshot.h"
00109 #include "llfloatertools.h"
00110 #include "llfloaterworldmap.h"
00111 #include "llfocusmgr.h"
00112 #include "llframestatview.h"
00113 #include "llgesturemgr.h"
00114 #include "llglheaders.h"
00115 #include "llhippo.h"
00116 #include "llhoverview.h"
00117 #include "llhudmanager.h"
00118 #include "llhudview.h"
00119 #include "llimagebmp.h"
00120 #include "llimagej2c.h"
00121 #include "llinventoryview.h"
00122 #include "llkeyboard.h"
00123 #include "lllineeditor.h"
00124 #include "llmenugl.h"
00125 #include "llmodaldialog.h"
00126 #include "llmorphview.h"
00127 #include "llmoveview.h"
00128 #include "llnotify.h"
00129 #include "lloverlaybar.h"
00130 #include "llpreviewtexture.h"
00131 #include "llprogressview.h"
00132 #include "llresmgr.h"
00133 #include "llrootview.h"
00134 #include "llselectmgr.h"
00135 #include "llrendersphere.h"
00136 #include "llstartup.h"
00137 #include "llstatusbar.h"
00138 #include "llstatview.h"
00139 #include "llsurface.h"
00140 #include "llsurfacepatch.h"
00141 #include "llimview.h"
00142 #include "lltexlayer.h"
00143 #include "lltextbox.h"
00144 #include "lltexturecache.h"
00145 #include "lltexturefetch.h"
00146 #include "lltextureview.h"
00147 #include "lltool.h"
00148 #include "lltoolbar.h"
00149 #include "lltoolcomp.h"
00150 #include "lltooldraganddrop.h"
00151 #include "lltoolface.h"
00152 #include "lltoolfocus.h"
00153 #include "lltoolgrab.h"
00154 #include "lltoolmgr.h"
00155 #include "lltoolmorph.h"
00156 #include "lltoolpie.h"
00157 #include "lltoolplacer.h"
00158 #include "lltoolselectland.h"
00159 #include "lltoolview.h"
00160 #include "lluictrlfactory.h"
00161 #include "lluploaddialog.h"
00162 #include "llurldispatcher.h"
00163 #include "llvieweraudio.h"
00164 #include "llviewercamera.h"
00165 #include "llviewergesture.h"
00166 #include "llviewerimagelist.h"
00167 #include "llviewerinventory.h"
00168 #include "llviewerkeyboard.h"
00169 #include "llviewermenu.h"
00170 #include "llviewermessage.h"
00171 #include "llviewerobjectlist.h"
00172 #include "llviewerparcelmgr.h"
00173 #include "llviewerregion.h"
00174 #include "llviewerstats.h"
00175 #include "llvoavatar.h"
00176 #include "llvovolume.h"
00177 #include "llworld.h"
00178 #include "llworldmapview.h"
00179 #include "pipeline.h"
00180 #include "llappviewer.h"
00181 #include "llurlsimstring.h"
00182 #include "llviewerdisplay.h"
00183 #include "llspatialpartition.h"
00184 #include "llviewerjoystick.h"
00185
00186 #if LL_WINDOWS
00187 #include "llwindebug.h"
00188 #include <tchar.h>
00189 #endif
00190
00191
00192
00193
00194 void render_ui_and_swap_if_needed();
00195 void render_ui_and_swap();
00196 LLBottomPanel* gBottomPanel = NULL;
00197
00198 extern BOOL gDebugClicks;
00199 extern BOOL gDisplaySwapBuffers;
00200 extern BOOL gResizeScreenTexture;
00201 extern S32 gJamesInt;
00202
00203 LLViewerWindow *gViewerWindow = NULL;
00204 LLVelocityBar *gVelocityBar = NULL;
00205
00206 LLVector3d gLastHitPosGlobal;
00207 LLVector3d gLastHitObjectOffset;
00208 LLUUID gLastHitObjectID;
00209 S32 gLastHitObjectFace = -1;
00210 BOOL gLastHitLand = FALSE;
00211 F32 gLastHitUCoord;
00212 F32 gLastHitVCoord;
00213
00214
00215 LLVector3d gLastHitNonFloraPosGlobal;
00216 LLVector3d gLastHitNonFloraObjectOffset;
00217 LLUUID gLastHitNonFloraObjectID;
00218 S32 gLastHitNonFloraObjectFace = -1;
00219 BOOL gLastHitParcelWall = FALSE;
00220
00221 S32 gLastHitUIElement = 0;
00222 LLHUDIcon* gLastHitHUDIcon = NULL;
00223
00224 BOOL gDebugSelect = FALSE;
00225 U8 gLastPickAlpha = 255;
00226 BOOL gUseGLPick = FALSE;
00227
00228
00229
00230
00231 BOOL gPickFaces = FALSE;
00232
00233 LLFrameTimer gMouseIdleTimer;
00234 LLFrameTimer gAwayTimer;
00235 LLFrameTimer gAwayTriggerTimer;
00236 LLFrameTimer gAlphaFadeTimer;
00237
00238 BOOL gShowOverlayTitle = FALSE;
00239 BOOL gPickTransparent = TRUE;
00240
00241 BOOL gDebugFastUIRender = FALSE;
00242
00243
00244 BOOL gDisplayWindInfo = FALSE;
00245 BOOL gDisplayCameraPos = FALSE;
00246 BOOL gDisplayNearestWater = FALSE;
00247 BOOL gDisplayFOV = FALSE;
00248
00249 S32 CHAT_BAR_HEIGHT = 28;
00250 S32 OVERLAY_BAR_HEIGHT = 20;
00251
00252 const U8 NO_FACE = 255;
00253 BOOL gQuietSnapshot = FALSE;
00254
00255 const F32 MIN_AFK_TIME = 2.f;
00256 const F32 MAX_FAST_FRAME_TIME = 0.5f;
00257 const F32 FAST_FRAME_INCREMENT = 0.1f;
00258
00259 const S32 PICK_HALF_WIDTH = 5;
00260 const S32 PICK_DIAMETER = 2 * PICK_HALF_WIDTH+1;
00261
00262 const F32 MIN_DISPLAY_SCALE = 0.85f;
00263
00264 const S32 CONSOLE_BOTTOM_PAD = 40;
00265 #ifdef SABINRIG
00267 bool rigControl = false;
00268 bool voltDisplay = true;
00269 bool nominalX = false;
00270 bool nominalY = false;
00271 static F32 nomerX = 0.0f;
00272 static F32 nomerY = 0.0f;
00273 const BOARD_NUM = 0;
00274 const ADRANGE = BIP10VOLTS;
00275 static unsigned short DataVal;
00276 static F32 oldValueX = 0;
00277 static F32 newValueX = 50;
00278 static F32 oldValueY = 0;
00279 static F32 newValueY = 50;
00280 static S32 mouseX = 50;
00281 static S32 mouseY = 50;
00282 static float VoltageX = 50;
00283 static float VoltageY = 50;
00284 static float nVoltX = 0;
00285 static float nVoltY = 0;
00286 static F32 temp1 = 50.f;
00287 static F32 temp2 = 20.f;
00288 LLCoordGL new_gl;
00289 #endif //SABINRIG
00290
00291 char LLViewerWindow::sSnapshotBaseName[LL_MAX_PATH];
00292 char LLViewerWindow::sSnapshotDir[LL_MAX_PATH];
00293
00294 char LLViewerWindow::sMovieBaseName[LL_MAX_PATH];
00295
00296 extern void toggle_debug_menus(void*);
00297
00298 #ifdef SABINRIG
00299
00300 void LLViewerWindow::printFeedback()
00301 {
00302 if(rigControl == true)
00303 {
00304 cbAIn (BOARD_NUM, 0, ADRANGE, &DataVal);
00305 cbToEngUnits (BOARD_NUM,ADRANGE,DataVal,&VoltageX);
00306 cbAIn (BOARD_NUM, 1, ADRANGE, &DataVal);
00307 cbToEngUnits (BOARD_NUM,ADRANGE,DataVal,&VoltageY);
00308 if(voltDisplay == true)
00309 {
00310 llinfos << "Current Voltages - X:" << VoltageX << " Y:" << VoltageY << llendl;
00311 }
00312
00313 if(nVoltX == 0)
00314 {
00315 nVoltX = VoltageX;
00316 nVoltY = VoltageY;
00317 }
00318
00319 newValueX = VoltageX;
00320 newValueY = VoltageY;
00321
00322 mouseX = mCurrentMousePoint.mX;
00323 mouseY = mCurrentMousePoint.mY;
00324
00325 if( abs(newValueX - nVoltX) > nomerX )
00326 {
00327 if( (newValueX - oldValueX) < 0)
00328 {
00329 mouseX += (S32)( ((newValueX - oldValueX)*.5)) * -temp;
00330 }
00331 else
00332 {
00333 mouseX += (S32)( ((newValueX - oldValueX)*.5) * temp1);
00334 }
00335 }
00336 else
00337 {
00338 mouseX = getWindowWidth() / 2;
00339 }
00340 if( abs(newValueY - nVoltY) > nomerY )
00341 {
00342 if( (newValueY - oldValueY) < 0)
00343 {
00344 mouseY += (S32)( ((newValueY - oldValueY)*(newValueY - oldValueY)) * -temp2);
00345 }
00346 else
00347 {
00348 mouseY += (S32)( ((newValueY - oldValueY)*(newValueY - oldValueY)) * temp2);
00349 }
00350 }
00351 else
00352 {
00353 mouseY = getWindowHeight() / 2;
00354 }
00355
00356
00357
00358
00359
00360
00361
00362
00363 oldValueX = newValueX;
00364 oldValueY = newValueY;
00365
00366 new_gl.mX = mouseX;
00367 new_gl.mY = mouseY;
00368
00369 setCursorPosition(new_gl);
00370 }
00371 }
00372 #endif //SABINRIG
00373
00375
00376
00377
00378
00379 class LLDebugText
00380 {
00381 private:
00382 struct Line
00383 {
00384 Line(const std::string& in_text, S32 in_x, S32 in_y) : text(in_text), x(in_x), y(in_y) {}
00385 std::string text;
00386 S32 x,y;
00387 };
00388
00389 LLViewerWindow *mWindow;
00390
00391 typedef std::vector<Line> line_list_t;
00392 line_list_t mLineList;
00393 LLColor4 mTextColor;
00394
00395 public:
00396 LLDebugText(LLViewerWindow* window) : mWindow(window) {}
00397
00398 void addText(S32 x, S32 y, const std::string &text)
00399 {
00400 mLineList.push_back(Line(text, x, y));
00401 }
00402
00403 void update()
00404 {
00405 std::string wind_vel_text;
00406 std::string wind_vector_text;
00407 std::string rwind_vel_text;
00408 std::string rwind_vector_text;
00409 std::string audio_text;
00410
00411
00412
00413 mTextColor = LLColor4( 0.86f, 0.86f, 0.86f, 1.f );
00414
00415
00416 U32 xpos = mWindow->getWindowWidth() - 350;
00417 U32 ypos = 64;
00418 const U32 y_inc = 20;
00419
00420 if (gSavedSettings.getBOOL("DebugShowTime"))
00421 {
00422 const U32 y_inc2 = 15;
00423 for (std::map<S32,LLFrameTimer>::reverse_iterator iter = gDebugTimers.rbegin();
00424 iter != gDebugTimers.rend(); ++iter)
00425 {
00426 S32 idx = iter->first;
00427 LLFrameTimer& timer = iter->second;
00428 F32 time = timer.getElapsedTimeF32();
00429 S32 hours = (S32)(time / (60*60));
00430 S32 mins = (S32)((time - hours*(60*60)) / 60);
00431 S32 secs = (S32)((time - hours*(60*60) - mins*60));
00432 addText(xpos, ypos, llformat(" Debug %d: %d:%02d:%02d", idx, hours,mins,secs)); ypos += y_inc2;
00433 }
00434
00435 F32 time = gFrameTimeSeconds;
00436 S32 hours = (S32)(time / (60*60));
00437 S32 mins = (S32)((time - hours*(60*60)) / 60);
00438 S32 secs = (S32)((time - hours*(60*60) - mins*60));
00439 addText(xpos, ypos, llformat("Time: %d:%02d:%02d", hours,mins,secs)); ypos += y_inc;
00440 }
00441
00442 if (gDisplayCameraPos)
00443 {
00444 std::string camera_view_text;
00445 std::string camera_center_text;
00446 std::string agent_view_text;
00447 std::string agent_left_text;
00448 std::string agent_center_text;
00449 std::string agent_root_center_text;
00450
00451 LLVector3d tvector;
00452
00453
00454 tvector = gAgent.getPositionGlobal();
00455 agent_center_text = llformat("AgentCenter %f %f %f",
00456 (F32)(tvector.mdV[VX]), (F32)(tvector.mdV[VY]), (F32)(tvector.mdV[VZ]));
00457
00458 if (gAgent.getAvatarObject())
00459 {
00460 tvector = gAgent.getPosGlobalFromAgent(gAgent.getAvatarObject()->mRoot.getWorldPosition());
00461 agent_root_center_text = llformat("AgentRootCenter %f %f %f",
00462 (F32)(tvector.mdV[VX]), (F32)(tvector.mdV[VY]), (F32)(tvector.mdV[VZ]));
00463 }
00464 else
00465 {
00466 agent_root_center_text = "---";
00467 }
00468
00469
00470 tvector = LLVector4(gAgent.getFrameAgent().getAtAxis());
00471 agent_view_text = llformat("AgentAtAxis %f %f %f",
00472 (F32)(tvector.mdV[VX]), (F32)(tvector.mdV[VY]), (F32)(tvector.mdV[VZ]));
00473
00474 tvector = LLVector4(gAgent.getFrameAgent().getLeftAxis());
00475 agent_left_text = llformat("AgentLeftAxis %f %f %f",
00476 (F32)(tvector.mdV[VX]), (F32)(tvector.mdV[VY]), (F32)(tvector.mdV[VZ]));
00477
00478 tvector = gAgent.getCameraPositionGlobal();
00479 camera_center_text = llformat("CameraCenter %f %f %f",
00480 (F32)(tvector.mdV[VX]), (F32)(tvector.mdV[VY]), (F32)(tvector.mdV[VZ]));
00481
00482 tvector = LLVector4(LLViewerCamera::getInstance()->getAtAxis());
00483 camera_view_text = llformat("CameraAtAxis %f %f %f",
00484 (F32)(tvector.mdV[VX]), (F32)(tvector.mdV[VY]), (F32)(tvector.mdV[VZ]));
00485
00486 addText(xpos, ypos, agent_center_text); ypos += y_inc;
00487 addText(xpos, ypos, agent_root_center_text); ypos += y_inc;
00488 addText(xpos, ypos, agent_view_text); ypos += y_inc;
00489 addText(xpos, ypos, agent_left_text); ypos += y_inc;
00490 addText(xpos, ypos, camera_center_text); ypos += y_inc;
00491 addText(xpos, ypos, camera_view_text); ypos += y_inc;
00492 }
00493
00494 if (gDisplayWindInfo)
00495 {
00496 wind_vel_text = llformat("Wind velocity %.2f m/s", gWindVec.magVec());
00497 wind_vector_text = llformat("Wind vector %.2f %.2f %.2f", gWindVec.mV[0], gWindVec.mV[1], gWindVec.mV[2]);
00498 rwind_vel_text = llformat("RWind vel %.2f m/s", gRelativeWindVec.magVec());
00499 rwind_vector_text = llformat("RWind vec %.2f %.2f %.2f", gRelativeWindVec.mV[0], gRelativeWindVec.mV[1], gRelativeWindVec.mV[2]);
00500
00501 addText(xpos, ypos, wind_vel_text); ypos += y_inc;
00502 addText(xpos, ypos, wind_vector_text); ypos += y_inc;
00503 addText(xpos, ypos, rwind_vel_text); ypos += y_inc;
00504 addText(xpos, ypos, rwind_vector_text); ypos += y_inc;
00505 }
00506 if (gDisplayWindInfo)
00507 {
00508 if (gAudiop)
00509 {
00510 audio_text= llformat("Audio for wind: %d", gAudiop->isWindEnabled());
00511 }
00512 addText(xpos, ypos, audio_text); ypos += y_inc;
00513 }
00514 if (gDisplayFOV)
00515 {
00516 addText(xpos, ypos, llformat("FOV: %2.1f deg", RAD_TO_DEG * LLViewerCamera::getInstance()->getView()));
00517 ypos += y_inc;
00518 }
00519
00520 if (LLViewerJoystick::getInstance()->getOverrideCamera())
00521 {
00522 addText(xpos + 200, ypos, llformat("Flycam"));
00523 ypos += y_inc;
00524 }
00525
00526 if (gSavedSettings.getBOOL("DebugShowRenderInfo"))
00527 {
00528 if (gPipeline.getUseVertexShaders() == 0)
00529 {
00530 addText(xpos, ypos, "Shaders Disabled");
00531 ypos += y_inc;
00532 }
00533 addText(xpos, ypos, llformat("%d MB Vertex Data", LLVertexBuffer::sAllocatedBytes/(1024*1024)));
00534 ypos += y_inc;
00535
00536 addText(xpos, ypos, llformat("%d Vertex Buffers", LLVertexBuffer::sGLCount));
00537 ypos += y_inc;
00538
00539 addText(xpos, ypos, llformat("%d Mapped Buffers", LLVertexBuffer::sMappedCount));
00540 ypos += y_inc;
00541
00542 addText(xpos, ypos, llformat("%d Vertex Buffer Binds", LLVertexBuffer::sBindCount));
00543 ypos += y_inc;
00544
00545 addText(xpos, ypos, llformat("%d Vertex Buffer Sets", LLVertexBuffer::sSetCount));
00546 ypos += y_inc;
00547
00548 addText(xpos, ypos, llformat("%d Texture Binds", LLImageGL::sBindCount));
00549 ypos += y_inc;
00550
00551 addText(xpos, ypos, llformat("%d Unique Textures", LLImageGL::sUniqueCount));
00552 ypos += y_inc;
00553
00554 addText(xpos, ypos, llformat("%d Render Calls", gPipeline.mBatchCount));
00555 ypos += y_inc;
00556
00557 addText(xpos, ypos, llformat("%d Matrix Ops", gPipeline.mMatrixOpCount));
00558 ypos += y_inc;
00559
00560 addText(xpos, ypos, llformat("%d Texture Matrix Ops", gPipeline.mTextureMatrixOps));
00561 ypos += y_inc;
00562
00563 gPipeline.mTextureMatrixOps = 0;
00564 gPipeline.mMatrixOpCount = 0;
00565
00566 if (gPipeline.mBatchCount > 0)
00567 {
00568 addText(xpos, ypos, llformat("Batch min/max/mean: %d/%d/%d", gPipeline.mMinBatchSize, gPipeline.mMaxBatchSize,
00569 gPipeline.mMeanBatchSize));
00570
00571 gPipeline.mMinBatchSize = gPipeline.mMaxBatchSize;
00572 gPipeline.mMaxBatchSize = 0;
00573 gPipeline.mBatchCount = 0;
00574 }
00575 ypos += y_inc;
00576
00577 addText(xpos,ypos, llformat("%d/%d Nodes visible", gPipeline.mNumVisibleNodes, LLSpatialGroup::sNodeCount));
00578
00579 ypos += y_inc;
00580
00581
00582 addText(xpos,ypos, llformat("%d Avatars visible", LLVOAvatar::sNumVisibleAvatars));
00583
00584 ypos += y_inc;
00585
00586 LLVertexBuffer::sBindCount = LLImageGL::sBindCount =
00587 LLVertexBuffer::sSetCount = LLImageGL::sUniqueCount =
00588 gPipeline.mNumVisibleNodes = 0;
00589 }
00590 if (gSavedSettings.getBOOL("DebugShowColor"))
00591 {
00592 U8 color[4];
00593 LLCoordGL coord = gViewerWindow->getCurrentMouse();
00594 glReadPixels(coord.mX, coord.mY, 1,1,GL_RGBA, GL_UNSIGNED_BYTE, color);
00595 addText(xpos, ypos, llformat("%d %d %d %d", color[0], color[1], color[2], color[3]));
00596 ypos += y_inc;
00597 }
00598
00599 if (LLPipeline::getRenderBeacons(NULL) && LLPipeline::getProcessBeacons(NULL))
00600 {
00601 if (LLPipeline::getRenderParticleBeacons(NULL))
00602 {
00603 addText(xpos, ypos, "Viewing particle beacons (blue)");
00604 ypos += y_inc;
00605 }
00606 if (LLPipeline::toggleRenderTypeControlNegated((void*)LLPipeline::RENDER_TYPE_PARTICLES))
00607 {
00608 addText(xpos, ypos, "Hiding particles");
00609 ypos += y_inc;
00610 }
00611 if (LLPipeline::getRenderPhysicalBeacons(NULL))
00612 {
00613 addText(xpos, ypos, "Viewing physical object beacons (green)");
00614 ypos += y_inc;
00615 }
00616 if (LLPipeline::getRenderScriptedBeacons(NULL))
00617 {
00618 addText(xpos, ypos, "Viewing scripted object beacons (red)");
00619 ypos += y_inc;
00620 }
00621 else
00622 if (LLPipeline::getRenderScriptedTouchBeacons(NULL))
00623 {
00624 addText(xpos, ypos, "Viewing scripted object with touch function beacons (red)");
00625 ypos += y_inc;
00626 }
00627 if (LLPipeline::getRenderSoundBeacons(NULL))
00628 {
00629 addText(xpos, ypos, "Viewing sound beacons (yellow)");
00630 ypos += y_inc;
00631 }
00632 }
00633 }
00634
00635 void draw()
00636 {
00637 for (line_list_t::iterator iter = mLineList.begin();
00638 iter != mLineList.end(); ++iter)
00639 {
00640 const Line& line = *iter;
00641 LLFontGL::sMonospace->renderUTF8(line.text, 0, (F32)line.x, (F32)line.y, mTextColor,
00642 LLFontGL::LEFT, LLFontGL::TOP,
00643 LLFontGL::NORMAL, S32_MAX, S32_MAX, NULL, FALSE);
00644 }
00645 mLineList.clear();
00646 }
00647
00648 };
00649
00650 void LLViewerWindow::updateDebugText()
00651 {
00652 mDebugText->update();
00653 }
00654
00656
00657
00658
00659
00660 BOOL LLViewerWindow::handleMouseDown(LLWindow *window, LLCoordGL pos, MASK mask)
00661 {
00662 S32 x = pos.mX;
00663 S32 y = pos.mY;
00664 x = llround((F32)x / mDisplayScale.mV[VX]);
00665 y = llround((F32)y / mDisplayScale.mV[VY]);
00666
00667 LLView::sMouseHandlerMessage = "";
00668
00669 if (gDebugClicks)
00670 {
00671 llinfos << "ViewerWindow left mouse down at " << x << "," << y << llendl;
00672 }
00673
00674 if (gMenuBarView)
00675 {
00676
00677 gMenuBarView->resetMenuTrigger();
00678 }
00679
00680 mLeftMouseDown = TRUE;
00681
00682
00683 mWindow->captureMouse();
00684
00685
00686 gMouseIdleTimer.reset();
00687
00688
00689 if( mToolTip )
00690 {
00691 mToolTipBlocked = TRUE;
00692 mToolTip->setVisible( FALSE );
00693 }
00694
00695
00696 if (gHoverView)
00697 {
00698 gHoverView->cancelHover();
00699 }
00700
00701
00702 if( LLToolMgr::getInstance()->getCurrentTool()->clipMouseWhenDown() )
00703 {
00704 mWindow->setMouseClipping(TRUE);
00705 }
00706
00707 LLMouseHandler* mouse_captor = gFocusMgr.getMouseCapture();
00708 if( mouse_captor )
00709 {
00710 S32 local_x;
00711 S32 local_y;
00712 mouse_captor->screenPointToLocal( x, y, &local_x, &local_y );
00713 if (LLView::sDebugMouseHandling)
00714 {
00715 llinfos << "Left Mouse Down handled by captor " << mouse_captor->getName() << llendl;
00716 }
00717
00718 return mouse_captor->handleMouseDown(local_x, local_y, mask);
00719 }
00720
00721
00722 LLUICtrl* top_ctrl = gFocusMgr.getTopCtrl();
00723 if (top_ctrl)
00724 {
00725 S32 local_x, local_y;
00726 top_ctrl->screenPointToLocal( x, y, &local_x, &local_y );
00727 if (top_ctrl->pointInView(local_x, local_y))
00728 {
00729 return top_ctrl->handleMouseDown(local_x, local_y, mask);
00730 }
00731 else
00732 {
00733 setTopCtrl(NULL);
00734 }
00735 }
00736
00737
00738 if( mRootView->handleMouseDown(x, y, mask) )
00739 {
00740 if (LLView::sDebugMouseHandling)
00741 {
00742 llinfos << "Left Mouse Down" << LLView::sMouseHandlerMessage << llendl;
00743 }
00744 return TRUE;
00745 }
00746 else if (LLView::sDebugMouseHandling)
00747 {
00748 llinfos << "Left Mouse Down not handled by view" << llendl;
00749 }
00750
00751 if (gDisconnected)
00752 {
00753 return FALSE;
00754 }
00755
00756 if(LLToolMgr::getInstance()->getCurrentTool()->handleMouseDown( x, y, mask ) )
00757 {
00758
00759
00760
00761 gFocusMgr.setKeyboardFocus(NULL);
00762 return TRUE;
00763 }
00764
00765 return FALSE;
00766 }
00767
00768 BOOL LLViewerWindow::handleDoubleClick(LLWindow *window, LLCoordGL pos, MASK mask)
00769 {
00770 S32 x = pos.mX;
00771 S32 y = pos.mY;
00772 x = llround((F32)x / mDisplayScale.mV[VX]);
00773 y = llround((F32)y / mDisplayScale.mV[VY]);
00774
00775 LLView::sMouseHandlerMessage = "";
00776
00777 if (gDebugClicks)
00778 {
00779 llinfos << "ViewerWindow left mouse double-click at " << x << "," << y << llendl;
00780 }
00781
00782 mLeftMouseDown = TRUE;
00783
00784
00785 if( mToolTip )
00786 {
00787 mToolTip->setVisible( FALSE );
00788 }
00789
00790 LLMouseHandler* mouse_captor = gFocusMgr.getMouseCapture();
00791 if( mouse_captor )
00792 {
00793 S32 local_x;
00794 S32 local_y;
00795 mouse_captor->screenPointToLocal( x, y, &local_x, &local_y );
00796 if (LLView::sDebugMouseHandling)
00797 {
00798 llinfos << "Left Mouse Down handled by captor " << mouse_captor->getName() << llendl;
00799 }
00800
00801 return mouse_captor->handleDoubleClick(local_x, local_y, mask);
00802 }
00803
00804
00805 LLUICtrl* top_ctrl = gFocusMgr.getTopCtrl();
00806 if (top_ctrl)
00807 {
00808 S32 local_x, local_y;
00809 top_ctrl->screenPointToLocal( x, y, &local_x, &local_y );
00810 if (top_ctrl->pointInView(local_x, local_y))
00811 {
00812 return top_ctrl->handleDoubleClick(local_x, local_y, mask);
00813 }
00814 else
00815 {
00816 setTopCtrl(NULL);
00817 }
00818 }
00819
00820 if (mRootView->handleDoubleClick(x, y, mask))
00821 {
00822 if (LLView::sDebugMouseHandling)
00823 {
00824 llinfos << "Left Mouse Down" << LLView::sMouseHandlerMessage << llendl;
00825 }
00826 return TRUE;
00827 }
00828 else if (LLView::sDebugMouseHandling)
00829 {
00830 llinfos << "Left Mouse Down not handled by view" << llendl;
00831 }
00832
00833
00834 if (gNoRender)
00835 {
00836 return TRUE;
00837 }
00838
00839 if(LLToolMgr::getInstance()->getCurrentTool()->handleDoubleClick( x, y, mask ) )
00840 {
00841 return TRUE;
00842 }
00843
00844
00845 return handleMouseDown(window, pos, mask);
00846 }
00847
00848 BOOL LLViewerWindow::handleMouseUp(LLWindow *window, LLCoordGL pos, MASK mask)
00849 {
00850 S32 x = pos.mX;
00851 S32 y = pos.mY;
00852 x = llround((F32)x / mDisplayScale.mV[VX]);
00853 y = llround((F32)y / mDisplayScale.mV[VY]);
00854
00855 LLView::sMouseHandlerMessage = "";
00856
00857 if (gDebugClicks)
00858 {
00859 llinfos << "ViewerWindow left mouse up" << llendl;
00860 }
00861
00862 mLeftMouseDown = FALSE;
00863
00864
00865 gMouseIdleTimer.reset();
00866
00867
00868 if( mToolTip )
00869 {
00870 mToolTip->setVisible( FALSE );
00871 }
00872
00873
00874 if (gHoverView) gHoverView->cancelHover();
00875
00876 BOOL handled = FALSE;
00877
00878 mWindow->releaseMouse();
00879
00880 LLTool *tool = LLToolMgr::getInstance()->getCurrentTool();
00881
00882 if( tool->clipMouseWhenDown() )
00883 {
00884 mWindow->setMouseClipping(FALSE);
00885 }
00886
00887 LLMouseHandler* mouse_captor = gFocusMgr.getMouseCapture();
00888 if( mouse_captor )
00889 {
00890 S32 local_x;
00891 S32 local_y;
00892 mouse_captor->screenPointToLocal( x, y, &local_x, &local_y );
00893 if (LLView::sDebugMouseHandling)
00894 {
00895 llinfos << "Left Mouse Up handled by captor " << mouse_captor->getName() << llendl;
00896 }
00897
00898 return mouse_captor->handleMouseUp(local_x, local_y, mask);
00899 }
00900
00901 LLUICtrl* top_ctrl = gFocusMgr.getTopCtrl();
00902 if (top_ctrl)
00903 {
00904 S32 local_x, local_y;
00905 top_ctrl->screenPointToLocal( x, y, &local_x, &local_y );
00906 handled = top_ctrl->pointInView(local_x, local_y) && top_ctrl->handleMouseUp(local_x, local_y, mask);
00907 }
00908
00909 if( !handled )
00910 {
00911 handled = mRootView->handleMouseUp(x, y, mask);
00912 }
00913
00914 if (LLView::sDebugMouseHandling)
00915 {
00916 if (handled)
00917 {
00918 llinfos << "Left Mouse Up" << LLView::sMouseHandlerMessage << llendl;
00919 }
00920 else
00921 {
00922 llinfos << "Left Mouse Up not handled by view" << llendl;
00923 }
00924 }
00925
00926 if( !handled )
00927 {
00928 if (tool)
00929 {
00930 handled = tool->handleMouseUp(x, y, mask);
00931 }
00932 }
00933
00934
00935 return TRUE;
00936 }
00937
00938
00939 BOOL LLViewerWindow::handleRightMouseDown(LLWindow *window, LLCoordGL pos, MASK mask)
00940 {
00941 S32 x = pos.mX;
00942 S32 y = pos.mY;
00943 x = llround((F32)x / mDisplayScale.mV[VX]);
00944 y = llround((F32)y / mDisplayScale.mV[VY]);
00945
00946 LLView::sMouseHandlerMessage = "";
00947
00948 if (gDebugClicks)
00949 {
00950 llinfos << "ViewerWindow right mouse down at " << x << "," << y << llendl;
00951 }
00952
00953 if (gMenuBarView)
00954 {
00955
00956 gMenuBarView->resetMenuTrigger();
00957 }
00958
00959 mRightMouseDown = TRUE;
00960
00961
00962 mWindow->captureMouse();
00963
00964
00965 if( mToolTip )
00966 {
00967 mToolTip->setVisible( FALSE );
00968 }
00969
00970
00971 if (gHoverView)
00972 {
00973 gHoverView->cancelHover();
00974 }
00975
00976
00977 if( LLToolMgr::getInstance()->getCurrentTool()->clipMouseWhenDown() )
00978 {
00979 mWindow->setMouseClipping(TRUE);
00980 }
00981
00982 LLMouseHandler* mouse_captor = gFocusMgr.getMouseCapture();
00983 if( mouse_captor )
00984 {
00985 S32 local_x;
00986 S32 local_y;
00987 mouse_captor->screenPointToLocal( x, y, &local_x, &local_y );
00988 if (LLView::sDebugMouseHandling)
00989 {
00990 llinfos << "Right Mouse Down handled by captor " << mouse_captor->getName() << llendl;
00991 }
00992 return mouse_captor->handleRightMouseDown(local_x, local_y, mask);
00993 }
00994
00995 LLUICtrl* top_ctrl = gFocusMgr.getTopCtrl();
00996 if (top_ctrl)
00997 {
00998 S32 local_x, local_y;
00999 top_ctrl->screenPointToLocal( x, y, &local_x, &local_y );
01000 if (top_ctrl->pointInView(local_x, local_y))
01001 {
01002 return top_ctrl->handleRightMouseDown(local_x, local_y, mask);
01003 }
01004 else
01005 {
01006 setTopCtrl(NULL);
01007 }
01008 }
01009
01010 if( mRootView->handleRightMouseDown(x, y, mask) )
01011 {
01012 if (LLView::sDebugMouseHandling)
01013 {
01014 llinfos << "Right Mouse Down" << LLView::sMouseHandlerMessage << llendl;
01015 }
01016 return TRUE;
01017 }
01018 else if (LLView::sDebugMouseHandling)
01019 {
01020 llinfos << "Right Mouse Down not handled by view" << llendl;
01021 }
01022
01023 if(LLToolMgr::getInstance()->getCurrentTool()->handleRightMouseDown( x, y, mask ) )
01024 {
01025
01026
01027
01028 gFocusMgr.setKeyboardFocus(NULL);
01029 return TRUE;
01030 }
01031
01032
01033
01034 if (CAMERA_MODE_CUSTOMIZE_AVATAR != gAgent.getCameraMode())
01035 {
01036
01037
01038
01039 LLToolPie::getInstance()->handleRightMouseDown(x, y, mask);
01040
01041 }
01042
01043 return TRUE;
01044 }
01045
01046 BOOL LLViewerWindow::handleRightMouseUp(LLWindow *window, LLCoordGL pos, MASK mask)
01047 {
01048 S32 x = pos.mX;
01049 S32 y = pos.mY;
01050 x = llround((F32)x / mDisplayScale.mV[VX]);
01051 y = llround((F32)y / mDisplayScale.mV[VY]);
01052
01053 LLView::sMouseHandlerMessage = "";
01054
01055
01056 if (gDebugClicks)
01057 {
01058 llinfos << "ViewerWindow right mouse up" << llendl;
01059 }
01060
01061 mRightMouseDown = FALSE;
01062
01063
01064 gMouseIdleTimer.reset();
01065
01066
01067 if( mToolTip )
01068 {
01069 mToolTip->setVisible( FALSE );
01070 }
01071
01072
01073 if (gHoverView) gHoverView->cancelHover();
01074
01075 BOOL handled = FALSE;
01076
01077 mWindow->releaseMouse();
01078
01079 LLTool *tool = LLToolMgr::getInstance()->getCurrentTool();
01080
01081 if( tool->clipMouseWhenDown() )
01082 {
01083 mWindow->setMouseClipping(FALSE);
01084 }
01085
01086 LLMouseHandler* mouse_captor = gFocusMgr.getMouseCapture();
01087 if( mouse_captor )
01088 {
01089 S32 local_x;
01090 S32 local_y;
01091 mouse_captor->screenPointToLocal( x, y, &local_x, &local_y );
01092 if (LLView::sDebugMouseHandling)
01093 {
01094 llinfos << "Right Mouse Up handled by captor " << mouse_captor->getName() << llendl;
01095 }
01096 return mouse_captor->handleRightMouseUp(local_x, local_y, mask);
01097 }
01098
01099 LLUICtrl* top_ctrl = gFocusMgr.getTopCtrl();
01100 if (top_ctrl)
01101 {
01102 S32 local_x, local_y;
01103 top_ctrl->screenPointToLocal( x, y, &local_x, &local_y );
01104 handled = top_ctrl->pointInView(local_x, local_y) && top_ctrl->handleRightMouseUp(local_x, local_y, mask);
01105 }
01106
01107 if( !handled )
01108 {
01109 handled = mRootView->handleRightMouseUp(x, y, mask);
01110 }
01111
01112 if (LLView::sDebugMouseHandling)
01113 {
01114 if (handled)
01115 {
01116 llinfos << "Right Mouse Up" << LLView::sMouseHandlerMessage << llendl;
01117 }
01118 else
01119 {
01120 llinfos << "Right Mouse Up not handled by view" << llendl;
01121 }
01122 }
01123
01124 if( !handled )
01125 {
01126 if (tool)
01127 {
01128 handled = tool->handleRightMouseUp(x, y, mask);
01129 }
01130 }
01131
01132
01133 return TRUE;
01134 }
01135
01136 BOOL LLViewerWindow::handleMiddleMouseDown(LLWindow *window, LLCoordGL pos, MASK mask)
01137 {
01138 gVoiceClient->middleMouseState(true);
01139
01140
01141 return TRUE;
01142 }
01143
01144 BOOL LLViewerWindow::handleMiddleMouseUp(LLWindow *window, LLCoordGL pos, MASK mask)
01145 {
01146 gVoiceClient->middleMouseState(false);
01147
01148
01149 return TRUE;
01150 }
01151
01152 void LLViewerWindow::handleMouseMove(LLWindow *window, LLCoordGL pos, MASK mask)
01153 {
01154 S32 x = pos.mX;
01155 S32 y = pos.mY;
01156
01157 x = llround((F32)x / mDisplayScale.mV[VX]);
01158 y = llround((F32)y / mDisplayScale.mV[VY]);
01159
01160 mMouseInWindow = TRUE;
01161
01162
01163
01164 LLCoordGL prev_saved_mouse_point = mCurrentMousePoint;
01165 LLCoordGL mouse_point(x, y);
01166 saveLastMouse(mouse_point);
01167 BOOL mouse_actually_moved = !gFocusMgr.getMouseCapture() &&
01168 ((prev_saved_mouse_point.mX != mCurrentMousePoint.mX) || (prev_saved_mouse_point.mY != mCurrentMousePoint.mY));
01169
01170 gMouseIdleTimer.reset();
01171
01172 mWindow->showCursorFromMouseMove();
01173
01174 if (gAwayTimer.getElapsedTimeF32() > MIN_AFK_TIME)
01175 {
01176 gAgent.clearAFK();
01177 }
01178
01179 if(mToolTip && mouse_actually_moved)
01180 {
01181 mToolTipBlocked = FALSE;
01182 if( mToolTip->getVisible() && !mToolTipStickyRect.pointInRect( x, y ) )
01183 {
01184 mToolTip->setVisible( FALSE );
01185 }
01186 }
01187
01188
01189 if (gHoverView)
01190 {
01191 gHoverView->setTyping(FALSE);
01192 }
01193 }
01194
01195 void LLViewerWindow::handleMouseLeave(LLWindow *window)
01196 {
01197
01198 llassert( gFocusMgr.getMouseCapture() == NULL );
01199 mMouseInWindow = FALSE;
01200 if (mToolTip)
01201 {
01202 mToolTip->setVisible( FALSE );
01203 }
01204 }
01205
01206 BOOL LLViewerWindow::handleCloseRequest(LLWindow *window)
01207 {
01208
01209
01210 LLAppViewer::instance()->userQuit();
01211
01212 return FALSE;
01213 }
01214
01215 void LLViewerWindow::handleQuit(LLWindow *window)
01216 {
01217 LLAppViewer::instance()->forceQuit();
01218 }
01219
01220 void LLViewerWindow::handleResize(LLWindow *window, S32 width, S32 height)
01221 {
01222 reshape(width, height);
01223 }
01224
01225
01226 void LLViewerWindow::handleFocus(LLWindow *window)
01227 {
01228 gFocusMgr.setAppHasFocus(TRUE);
01229 LLModalDialog::onAppFocusGained();
01230
01231 gAgent.onAppFocusGained();
01232 LLToolMgr::getInstance()->onAppFocusGained();
01233
01234 gShowTextEditCursor = TRUE;
01235
01236
01237 if (gKeyboard)
01238 {
01239 gKeyboard->resetMaskKeys();
01240 }
01241
01242
01243
01244 gForegroundTime.unpause();
01245 }
01246
01247
01248 void LLViewerWindow::handleFocusLost(LLWindow *window)
01249 {
01250 gFocusMgr.setAppHasFocus(FALSE);
01251
01252 LLToolMgr::getInstance()->onAppFocusLost();
01253 gFocusMgr.setMouseCapture( NULL );
01254
01255 if (gMenuBarView)
01256 {
01257
01258 gMenuBarView->resetMenuTrigger();
01259 }
01260
01261
01262 showCursor();
01263 getWindow()->setMouseClipping(FALSE);
01264
01265
01266
01267
01268 gShowTextEditCursor = FALSE;
01269
01270
01271 if (gKeyboard)
01272 {
01273 gKeyboard->resetKeys();
01274 }
01275
01276
01277 gForegroundTime.pause();
01278 }
01279
01280
01281 BOOL LLViewerWindow::handleTranslatedKeyDown(KEY key, MASK mask, BOOL repeated)
01282 {
01283
01284 gVoiceClient->keyDown(key, mask);
01285
01286 if (gAwayTimer.getElapsedTimeF32() > MIN_AFK_TIME)
01287 {
01288 gAgent.clearAFK();
01289 }
01290
01291
01292
01293
01294
01295 if (key == KEY_RETURN && mask == MASK_NONE)
01296 {
01297 return FALSE;
01298 }
01299
01300 return gViewerKeyboard.handleKey(key, mask, repeated);
01301 }
01302
01303 BOOL LLViewerWindow::handleTranslatedKeyUp(KEY key, MASK mask)
01304 {
01305
01306 gVoiceClient->keyUp(key, mask);
01307
01308 return FALSE;
01309 }
01310
01311
01312 void LLViewerWindow::handleScanKey(KEY key, BOOL key_down, BOOL key_up, BOOL key_level)
01313 {
01314 LLViewerJoystick::getInstance()->setCameraNeedsUpdate(true);
01315 return gViewerKeyboard.scanKey(key, key_down, key_up, key_level);
01316 }
01317
01318
01319
01320
01321 BOOL LLViewerWindow::handleActivate(LLWindow *window, BOOL activated)
01322 {
01323 if (activated)
01324 {
01325 mActive = TRUE;
01326 send_agent_resume();
01327 gAgent.clearAFK();
01328 if (mWindow->getFullscreen() && !mIgnoreActivate)
01329 {
01330 if (!LLApp::isExiting() )
01331 {
01332 if (LLStartUp::getStartupState() >= STATE_STARTED)
01333 {
01334
01335 llinfos << "Restoring GL during activate" << llendl;
01336 restoreGL("Restoring...");
01337 }
01338 else
01339 {
01340
01341 restoreGL();
01342 }
01343 }
01344 else
01345 {
01346 llwarns << "Activating while quitting" << llendl;
01347 }
01348 }
01349
01350
01351 audio_update_volume();
01352 }
01353 else
01354 {
01355 mActive = FALSE;
01356 if (gAllowIdleAFK)
01357 {
01358 gAgent.setAFK();
01359 }
01360
01361
01362 gAgent.changeCameraToDefault();
01363
01364 send_agent_pause();
01365
01366 if (mWindow->getFullscreen() && !mIgnoreActivate)
01367 {
01368 llinfos << "Stopping GL during deactivation" << llendl;
01369 stopGL();
01370 }
01371
01372 audio_update_volume();
01373 }
01374 return TRUE;
01375 }
01376
01377 BOOL LLViewerWindow::handleActivateApp(LLWindow *window, BOOL activating)
01378 {
01379 LLViewerJoystick::getInstance()->setNeedsReset(true);
01380 return FALSE;
01381 }
01382
01383
01384 void LLViewerWindow::handleMenuSelect(LLWindow *window, S32 menu_item)
01385 {
01386 }
01387
01388
01389 BOOL LLViewerWindow::handlePaint(LLWindow *window, S32 x, S32 y, S32 width, S32 height)
01390 {
01391 #if LL_WINDOWS
01392 if (gNoRender)
01393 {
01394 HWND window_handle = (HWND)window->getPlatformWindow();
01395 PAINTSTRUCT ps;
01396 HDC hdc;
01397
01398 RECT wnd_rect;
01399 wnd_rect.left = 0;
01400 wnd_rect.top = 0;
01401 wnd_rect.bottom = 200;
01402 wnd_rect.right = 500;
01403
01404 hdc = BeginPaint(window_handle, &ps);
01405
01406 FillRect(hdc, &wnd_rect, CreateSolidBrush(RGB(255, 255, 255)));
01407
01408 LLString name_str;
01409 gAgent.getName(name_str);
01410
01411 S32 len;
01412 char temp_str[255];
01413 snprintf(temp_str, sizeof(temp_str), "%s FPS %3.1f Phy FPS %2.1f Time Dil %1.3f",
01414 name_str.c_str(),
01415 LLViewerStats::getInstance()->mFPSStat.getMeanPerSec(),
01416 LLViewerStats::getInstance()->mSimPhysicsFPS.getPrev(0),
01417 LLViewerStats::getInstance()->mSimTimeDilation.getPrev(0));
01418 len = strlen(temp_str);
01419 TextOutA(hdc, 0, 0, temp_str, len);
01420
01421
01422 LLVector3d pos_global = gAgent.getPositionGlobal();
01423 snprintf(temp_str, sizeof(temp_str), "Avatar pos %6.1lf %6.1lf %6.1lf", pos_global.mdV[0], pos_global.mdV[1], pos_global.mdV[2]);
01424 len = strlen(temp_str);
01425 TextOutA(hdc, 0, 25, temp_str, len);
01426
01427 TextOutA(hdc, 0, 50, "Set \"DisableRendering FALSE\" in settings.ini file to reenable", 61);
01428 EndPaint(window_handle, &ps);
01429 return TRUE;
01430 }
01431 #endif
01432 return FALSE;
01433 }
01434
01435
01436 void LLViewerWindow::handleScrollWheel(LLWindow *window, S32 clicks)
01437 {
01438 handleScrollWheel( clicks );
01439 }
01440
01441 void LLViewerWindow::handleWindowBlock(LLWindow *window)
01442 {
01443 send_agent_pause();
01444 }
01445
01446 void LLViewerWindow::handleWindowUnblock(LLWindow *window)
01447 {
01448 send_agent_resume();
01449 }
01450
01451 void LLViewerWindow::handleDataCopy(LLWindow *window, S32 data_type, void *data)
01452 {
01453 const S32 SLURL_MESSAGE_TYPE = 0;
01454 switch (data_type)
01455 {
01456 case SLURL_MESSAGE_TYPE:
01457
01458 std::string url = (const char*)data;
01459 const bool from_external_browser = true;
01460 if (LLURLDispatcher::dispatch(url, from_external_browser))
01461 {
01462
01463 mWindow->bringToFront();
01464 }
01465 break;
01466 }
01467 }
01468
01469 BOOL LLViewerWindow::handleTimerEvent(LLWindow *window)
01470 {
01471 if (LLViewerJoystick::getInstance()->getOverrideCamera())
01472 {
01473 LLViewerJoystick::getInstance()->updateStatus();
01474 return TRUE;
01475 }
01476 return FALSE;
01477 }
01478
01479 BOOL LLViewerWindow::handleDeviceChange(LLWindow *window)
01480 {
01481
01482 if (!LLViewerJoystick::getInstance()->isJoystickInitialized() )
01483 {
01484 LLViewerJoystick::getInstance()->init(true);
01485 return TRUE;
01486 }
01487 return FALSE;
01488 }
01489
01490
01491
01492
01493 LLViewerWindow::LLViewerWindow(
01494 char* title, char* name,
01495 S32 x, S32 y,
01496 S32 width, S32 height,
01497 BOOL fullscreen, BOOL ignore_pixel_depth)
01498 :
01499 mActive(TRUE),
01500 mWantFullscreen(fullscreen),
01501 mShowFullscreenProgress(FALSE),
01502 mWindowRect(0, height, width, 0),
01503 mVirtualWindowRect(0, height, width, 0),
01504 mLeftMouseDown(FALSE),
01505 mRightMouseDown(FALSE),
01506 mToolTip(NULL),
01507 mToolTipBlocked(FALSE),
01508 mMouseInWindow( FALSE ),
01509 mLastMask( MASK_NONE ),
01510 mToolStored( NULL ),
01511 mSuppressToolbox( FALSE ),
01512 mHideCursorPermanent( FALSE ),
01513 mPickPending(FALSE),
01514 mIgnoreActivate( FALSE )
01515 {
01516
01517 strcpy(LLViewerWindow::sSnapshotBaseName, "Snapshot");
01518 strcpy(LLViewerWindow::sMovieBaseName, "SLmovie");
01519 LLViewerWindow::sSnapshotDir[0] = '\0';
01520
01521
01522
01523 mWindow = LLWindowManager::createWindow(
01524 title, name, x, y, width, height, 0,
01525 fullscreen,
01526 gNoRender,
01527 gSavedSettings.getBOOL("DisableVerticalSync"),
01528 !gNoRender,
01529 ignore_pixel_depth,
01530 gSavedSettings.getU32("RenderFSAASamples"));
01531 #if LL_WINDOWS
01532 if (!LLWinDebug::checkExceptionHandler())
01533 {
01534 LL_WARNS("Window") << " Someone took over my exception handler (post createWindow)!" << LL_ENDL;
01535 }
01536 #endif
01537
01538 if (NULL == mWindow)
01539 {
01540 LLSplashScreen::update("Shutting down...");
01541 #if LL_LINUX || LL_SOLARIS
01542 llwarns << "Unable to create window, be sure screen is set at 32-bit color and your graphics driver is configured correctly. See README-linux.txt or README-solaris.txt for further information."
01543 << llendl;
01544 #else
01545 LL_WARNS("Window") << "Unable to create window, be sure screen is set at 32-bit color in Control Panels->Display->Settings"
01546 << LL_ENDL;
01547 #endif
01548 LLAppViewer::instance()->forceExit(1);
01549 }
01550
01551
01552
01553 F32 ui_scale_factor = gSavedSettings.getF32("UIScaleFactor");
01554
01555 mDisplayScale.setVec(llmax(1.f / mWindow->getPixelAspectRatio(), 1.f), llmax(mWindow->getPixelAspectRatio(), 1.f));
01556 mDisplayScale *= ui_scale_factor;
01557 LLUI::setScaleFactor(mDisplayScale);
01558
01559 {
01560 LLCoordWindow size;
01561 mWindow->getSize(&size);
01562 mWindowRect.set(0, size.mY, size.mX, 0);
01563 mVirtualWindowRect.set(0, llround((F32)size.mY / mDisplayScale.mV[VY]), llround((F32)size.mX / mDisplayScale.mV[VX]), 0);
01564 }
01565
01566 LLFontManager::initClass();
01567
01568
01569
01570
01571
01572 LL_DEBUGS("Window") << "Loading feature tables." << LL_ENDL;
01573
01574 LLFeatureManager::getInstance()->init();
01575
01576
01577 if (!LLFeatureManager::getInstance()->isFeatureAvailable("RenderVBOEnable") ||
01578 !gGLManager.mHasVertexBufferObject)
01579 {
01580 gSavedSettings.setBOOL("RenderVBOEnable", FALSE);
01581 }
01582 LLVertexBuffer::initClass(gSavedSettings.getBOOL("RenderVBOEnable"));
01583
01584 if (LLFeatureManager::getInstance()->isSafe()
01585 || (gSavedSettings.getS32("LastFeatureVersion") != LLFeatureManager::getInstance()->getVersion())
01586 || (gSavedSettings.getBOOL("ProbeHardwareOnStartup")))
01587 {
01588 LLFeatureManager::getInstance()->applyRecommendedSettings();
01589 gSavedSettings.setBOOL("ProbeHardwareOnStartup", FALSE);
01590 }
01591
01592
01593 if (gSavedSettings.getBOOL("RenderInitError"))
01594 {
01595 mInitAlert = "DisplaySettingsNoShaders";
01596 LLFeatureManager::getInstance()->setGraphicsLevel(0, false);
01597 gSavedSettings.setU32("RenderQualityPerformance", 0);
01598
01599 }
01600
01601
01602 mWindow->setCallbacks(this);
01603
01604
01605
01606 gImageList.init();
01607 LLViewerImage::initClass();
01608 gBumpImageList.init();
01609
01610
01611 mRootView = new LLRootView("root", mVirtualWindowRect, FALSE);
01612
01613 if (!gNoRender)
01614 {
01615
01616 initFonts();
01617 }
01618
01619
01620 mCurrentMousePoint.mX = getWindowWidth() / 2;
01621 mCurrentMousePoint.mY = getWindowHeight() / 2;
01622
01623 mPickBuffer = new U8[PICK_DIAMETER * PICK_DIAMETER * 4];
01624
01625 gShowOverlayTitle = gSavedSettings.getBOOL("ShowOverlayTitle");
01626 mOverlayTitle = gSavedSettings.getString("OverlayTitle");
01627
01628 LLString::replaceChar(mOverlayTitle, '_', ' ');
01629
01630 LLAlertDialog::setDisplayCallback(alertCallback);
01631
01632
01633 gSavedSettings.getControl("NumpadControl")->firePropertyChanged();
01634
01635 mDebugText = new LLDebugText(this);
01636
01637 }
01638
01639 void LLViewerWindow::initGLDefaults()
01640 {
01641 gGL.blendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
01642 glColorMaterial( GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE );
01643
01644 F32 ambient[4] = {0.f,0.f,0.f,0.f };
01645 F32 diffuse[4] = {1.f,1.f,1.f,1.f };
01646 glMaterialfv(GL_FRONT_AND_BACK,GL_AMBIENT,ambient);
01647 glMaterialfv(GL_FRONT_AND_BACK,GL_DIFFUSE,diffuse);
01648
01649 glPixelStorei(GL_PACK_ALIGNMENT,1);
01650 glPixelStorei(GL_UNPACK_ALIGNMENT,1);
01651
01652 glEnable(GL_TEXTURE_2D);
01653
01654
01655 glShadeModel( GL_SMOOTH );
01656
01657 glLightModelfv(GL_LIGHT_MODEL_AMBIENT, ambient);
01658
01659 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
01660
01661 glCullFace(GL_BACK);
01662
01663
01664 gCone.prerender();
01665 gBox.prerender();
01666 gSphere.prerender();
01667 gCylinder.prerender();
01668 }
01669
01670 void LLViewerWindow::initBase()
01671 {
01672 S32 height = getWindowHeight();
01673 S32 width = getWindowWidth();
01674
01675 LLRect full_window(0, height, width, 0);
01676
01677 adjustRectanglesForFirstUse(full_window);
01678
01680
01681
01682
01683
01684 F32 gamma = gSavedSettings.getF32("RenderGamma");
01685 if (gamma != 0.0f)
01686 {
01687 getWindow()->setGamma(gamma);
01688 }
01689
01690
01691
01692
01693
01694
01695
01696
01697 LLRect floater_view_rect = full_window;
01698
01699 floater_view_rect.mTop -= MENU_BAR_HEIGHT;
01700 floater_view_rect.mBottom += STATUS_BAR_HEIGHT + 12 + 16 + 2;
01701
01702
01703 S32 floater_view_bottom = gSavedSettings.getS32("FloaterViewBottom");
01704 if (floater_view_bottom >= 0)
01705 {
01706 floater_view_rect.mBottom = floater_view_bottom;
01707 }
01708 gFloaterView = new LLFloaterView("Floater View", floater_view_rect );
01709 gFloaterView->setVisible(TRUE);
01710
01711 gSnapshotFloaterView = new LLSnapshotFloaterView("Snapshot Floater View", full_window);
01712 gSnapshotFloaterView->setVisible(TRUE);
01713
01714
01715 llassert( !gConsole );
01716 LLRect console_rect = full_window;
01717 console_rect.mTop -= 24;
01718 console_rect.mBottom += STATUS_BAR_HEIGHT + 12 + 16 + 12;
01719 console_rect.mLeft += 24;
01720
01721 if (gSavedSettings.getBOOL("ChatFullWidth"))
01722 {
01723 console_rect.mRight -= 10;
01724 }
01725 else
01726 {
01727
01728
01729 console_rect.mRight = console_rect.mLeft + 2 * width / 3;
01730 }
01731
01732 gConsole = new LLConsole(
01733 "console",
01734 gSavedSettings.getS32("ConsoleBufferSize"),
01735 console_rect,
01736 gSavedSettings.getS32("ChatFontSize"),
01737 gSavedSettings.getF32("ChatPersistTime") );
01738 gConsole->setFollows(FOLLOWS_LEFT | FOLLOWS_RIGHT | FOLLOWS_BOTTOM);
01739 mRootView->addChild(gConsole);
01740
01741
01742 gDebugView = new LLDebugView("gDebugView", full_window);
01743 gDebugView->setFollowsAll();
01744 gDebugView->setVisible(TRUE);
01745 mRootView->addChild(gDebugView);
01746
01747
01748 mRootView->addChild(gFloaterView, -1);
01749 mRootView->addChild(gSnapshotFloaterView);
01750
01751
01752 LLRect notify_rect = full_window;
01753
01754 notify_rect.mBottom += STATUS_BAR_HEIGHT;
01755 gNotifyBoxView = new LLNotifyBoxView("notify_container", notify_rect, FALSE, FOLLOWS_ALL);
01756 mRootView->addChild(gNotifyBoxView, -2);
01757
01758
01759 mToolTip = new LLTextBox( "tool tip", LLRect(0, 1, 1, 0 ) );
01760 mToolTip->setHPad( 4 );
01761 mToolTip->setVPad( 2 );
01762 mToolTip->setColor( gColors.getColor( "ToolTipTextColor" ) );
01763 mToolTip->setBorderColor( gColors.getColor( "ToolTipBorderColor" ) );
01764 mToolTip->setBorderVisible( FALSE );
01765 mToolTip->setBackgroundColor( gColors.getColor( "ToolTipBgColor" ) );
01766 mToolTip->setBackgroundVisible( TRUE );
01767 mToolTip->setFontStyle(LLFontGL::NORMAL);
01768 mToolTip->setBorderDropshadowVisible( TRUE );
01769 mToolTip->setVisible( FALSE );
01770
01771
01772 mProgressView = new LLProgressView("ProgressView", full_window);
01773 mRootView->addChild(mProgressView);
01774 setShowProgress(FALSE);
01775 setProgressCancelButtonVisible(FALSE, "");
01776 }
01777
01778
01779 void adjust_rect_top_left(const LLString& control, const LLRect& window)
01780 {
01781 LLRect r = gSavedSettings.getRect(control);
01782 if (r.mLeft == 0 && r.mBottom == 0)
01783 {
01784 r.setLeftTopAndSize(0, window.getHeight(), r.getWidth(), r.getHeight());
01785 gSavedSettings.setRect(control, r);
01786 }
01787 }
01788
01789 void adjust_rect_top_center(const LLString& control, const LLRect& window)
01790 {
01791 LLRect r = gSavedSettings.getRect(control);
01792 if (r.mLeft == 0 && r.mBottom == 0)
01793 {
01794 r.setLeftTopAndSize( window.getWidth()/2 - r.getWidth()/2,
01795 window.getHeight(),
01796 r.getWidth(),
01797 r.getHeight() );
01798 gSavedSettings.setRect(control, r);
01799 }
01800 }
01801
01802 void adjust_rect_top_right(const LLString& control, const LLRect& window)
01803 {
01804 LLRect r = gSavedSettings.getRect(control);
01805 if (r.mLeft == 0 && r.mBottom == 0)
01806 {
01807 r.setLeftTopAndSize(window.getWidth() - r.getWidth(),
01808 window.getHeight(),
01809 r.getWidth(),
01810 r.getHeight());
01811 gSavedSettings.setRect(control, r);
01812 }
01813 }
01814
01815 void adjust_rect_bottom_center(const LLString& control, const LLRect& window)
01816 {
01817 LLRect r = gSavedSettings.getRect(control);
01818 if (r.mLeft == 0 && r.mBottom == 0)
01819 {
01820
01821 const S32 TOOLBAR_HEIGHT = 64;
01822 r.setOriginAndSize(
01823 window.getWidth()/2 - r.getWidth()/2,
01824 TOOLBAR_HEIGHT,
01825 r.getWidth(),
01826 r.getHeight());
01827 gSavedSettings.setRect(control, r);
01828 }
01829 }
01830
01831 void adjust_rect_centered_partial_zoom(const LLString& control,
01832 const LLRect& window)
01833 {
01834 LLRect rect = gSavedSettings.getRect(control);
01835
01836 if (rect.mLeft == 0 && rect.mBottom == 0)
01837 {
01838 S32 width = window.getWidth();
01839 S32 height = window.getHeight();
01840 rect.set(0, height-STATUS_BAR_HEIGHT, width, TOOL_BAR_HEIGHT);
01841
01842
01843 const F32 ZOOM_FRACTION = 0.8f;
01844 S32 dx = (S32)(width * (1.f - ZOOM_FRACTION));
01845 S32 dy = (S32)(height * (1.f - ZOOM_FRACTION));
01846 rect.stretch(-dx/2, -dy/2);
01847 gSavedSettings.setRect(control, rect);
01848 }
01849 }
01850
01851
01852
01853
01854 void LLViewerWindow::adjustRectanglesForFirstUse(const LLRect& window)
01855 {
01856 LLRect r;
01857
01858 adjust_rect_bottom_center("FloaterMoveRect2", window);
01859
01860 adjust_rect_top_center("FloaterCameraRect3", window);
01861
01862 adjust_rect_top_left("FloaterCustomizeAppearanceRect", window);
01863
01864 adjust_rect_top_left("FloaterLandRect5", window);
01865
01866 adjust_rect_top_left("FloaterHUDRect", window);
01867
01868 adjust_rect_top_left("FloaterFindRect2", window);
01869
01870 adjust_rect_top_left("FloaterGestureRect2", window);
01871
01872 adjust_rect_top_right("FloaterMiniMapRect", window);
01873
01874 adjust_rect_top_right("FloaterLagMeter", window);
01875
01876 adjust_rect_top_left("FloaterBuildOptionsRect", window);
01877
01878
01879 r = gSavedSettings.getRect("FloaterInventoryRect");
01880 if (r.mLeft == 0 && r.mBottom == 0)
01881 {
01882 r.setOriginAndSize(
01883 window.getWidth() - r.getWidth(),
01884 0,
01885 r.getWidth(),
01886 r.getHeight());
01887 gSavedSettings.setRect("FloaterInventoryRect", r);
01888 }
01889 }
01890
01891
01892 void LLViewerWindow::initWorldUI()
01893 {
01894 pre_init_menus();
01895
01896 S32 height = mRootView->getRect().getHeight();
01897 S32 width = mRootView->getRect().getWidth();
01898 LLRect full_window(0, height, width, 0);
01899
01900 if ( gBottomPanel == NULL )
01901 {
01902
01903 gBottomPanel = new LLBottomPanel(mRootView->getRect());
01904 mRootView->addChild(gBottomPanel);
01905
01906
01907 gHoverView = new LLHoverView("gHoverView", full_window);
01908 gHoverView->setVisible(TRUE);
01909 mRootView->addChild(gHoverView);
01910
01911
01912
01913
01914
01915 gFloaterMap = new LLFloaterMap("Map");
01916 gFloaterMap->setFollows(FOLLOWS_TOP|FOLLOWS_RIGHT);
01917
01918
01919 gFloaterView->adjustToFitScreen(gFloaterMap, FALSE);
01920
01921 gIMMgr = LLIMMgr::getInstance();
01922
01923 if ( gSavedPerAccountSettings.getBOOL("LogShowHistory") )
01924 {
01925 LLFloaterChat::getInstance(LLSD())->loadHistory();
01926 }
01927
01928 LLRect morph_view_rect = full_window;
01929 morph_view_rect.stretch( -STATUS_BAR_HEIGHT );
01930 morph_view_rect.mTop = full_window.mTop - 32;
01931 gMorphView = new LLMorphView("gMorphView", morph_view_rect );
01932 mRootView->addChild(gMorphView);
01933 gMorphView->setVisible(FALSE);
01934
01935
01936
01937 LLWorldMapView::initClass();
01938
01939 adjust_rect_centered_partial_zoom("FloaterWorldMapRect2", full_window);
01940
01941 gFloaterWorldMap = new LLFloaterWorldMap();
01942 gFloaterWorldMap->setVisible(FALSE);
01943
01944
01945
01946
01947
01948
01949 init_menus();
01950
01951 gFloaterTools = new LLFloaterTools();
01952 gFloaterTools->setVisible(FALSE);
01953
01954
01955 S32 menu_bar_height = gMenuBarView->getRect().getHeight();
01956 LLRect root_rect = getRootView()->getRect();
01957 LLRect status_rect(0, root_rect.getHeight(), root_rect.getWidth(), root_rect.getHeight() - menu_bar_height);
01958 gStatusBar = new LLStatusBar("status", status_rect);
01959 gStatusBar->setFollows(FOLLOWS_LEFT | FOLLOWS_RIGHT | FOLLOWS_TOP);
01960
01961 gStatusBar->reshape(root_rect.getWidth(), gStatusBar->getRect().getHeight(), TRUE);
01962 gStatusBar->translate(0, root_rect.getHeight() - gStatusBar->getRect().getHeight());
01963
01964 gStatusBar->setBackgroundColor( gMenuBarView->getBackgroundColor() );
01965
01966 LLFloaterChatterBox::createInstance(LLSD());
01967
01968 getRootView()->addChild(gStatusBar);
01969
01970
01971 getRootView()->sendChildToFront(gMenuHolder);
01972 }
01973 }
01974
01975
01976 LLViewerWindow::~LLViewerWindow()
01977 {
01978 delete mDebugText;
01979
01980 gSavedSettings.setS32("FloaterViewBottom", gFloaterView->getRect().mBottom);
01981
01982
01983 if (gMorphView)
01984 {
01985 gMorphView->setVisible(FALSE);
01986 }
01987
01988
01989 delete mRootView;
01990 mRootView = NULL;
01991
01992
01993 gFloaterTools = NULL;
01994 gStatusBar = NULL;
01995 gIMMgr = NULL;
01996 gHoverView = NULL;
01997
01998 gFloaterView = NULL;
01999 gMorphView = NULL;
02000
02001 gFloaterMap = NULL;
02002 gHUDView = NULL;
02003
02004 gNotifyBoxView = NULL;
02005
02006 delete mToolTip;
02007 mToolTip = NULL;
02008
02009
02010
02011
02012 LLFontGL::destroyDefaultFonts();
02013 LLFontManager::cleanupClass();
02014 stop_glerror();
02015
02016 gSky.cleanup();
02017 stop_glerror();
02018
02019 gImageList.shutdown();
02020 stop_glerror();
02021
02022 gBumpImageList.shutdown();
02023 stop_glerror();
02024
02025 LLWorldMapView::cleanupTextures();
02026
02027 llinfos << "Cleaning up pipeline" << llendl;
02028 gPipeline.cleanup();
02029 stop_glerror();
02030
02031 LLViewerImage::cleanupClass();
02032
02033 delete[] mPickBuffer;
02034 mPickBuffer = NULL;
02035
02036 llinfos << "Cleaning up select manager" << llendl;
02037 LLSelectMgr::getInstance()->cleanup();
02038
02039 LLVertexBuffer::cleanupClass();
02040
02041 llinfos << "Stopping GL during shutdown" << llendl;
02042 if (!gNoRender)
02043 {
02044 stopGL(FALSE);
02045 stop_glerror();
02046 }
02047
02048
02049 llinfos << "Destroying Window" << llendl;
02050 destroyWindow();
02051 }
02052
02053
02054 void LLViewerWindow::setCursor( ECursorType c )
02055 {
02056 mWindow->setCursor( c );
02057 }
02058
02059 void LLViewerWindow::showCursor()
02060 {
02061 mWindow->showCursor();
02062 }
02063
02064 void LLViewerWindow::hideCursor()
02065 {
02066
02067 if(mToolTip ) mToolTip->setVisible( FALSE );
02068
02069
02070 if (gHoverView) gHoverView->cancelHover();
02071
02072
02073 mWindow->hideCursor();
02074 }
02075
02076 void LLViewerWindow::sendShapeToSim()
02077 {
02078 LLMessageSystem* msg = gMessageSystem;
02079 if(!msg) return;
02080 msg->newMessageFast(_PREHASH_AgentHeightWidth);
02081 msg->nextBlockFast(_PREHASH_AgentData);
02082 msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
02083 msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
02084 msg->addU32Fast(_PREHASH_CircuitCode, gMessageSystem->mOurCircuitCode);
02085 msg->nextBlockFast(_PREHASH_HeightWidthBlock);
02086 msg->addU32Fast(_PREHASH_GenCounter, 0);
02087 U16 height16 = (U16) mWindowRect.getHeight();
02088 U16 width16 = (U16) mWindowRect.getWidth();
02089 msg->addU16Fast(_PREHASH_Height, height16);
02090 msg->addU16Fast(_PREHASH_Width, width16);
02091 gAgent.sendReliableMessage();
02092 }
02093
02094
02095
02096 void LLViewerWindow::reshape(S32 width, S32 height)
02097 {
02098
02099
02100
02101
02102 if (!LLApp::isExiting())
02103 {
02104 if (gNoRender)
02105 {
02106 return;
02107 }
02108
02109 glViewport(0, 0, width, height );
02110
02111 if (height > 0)
02112 {
02113 LLViewerCamera::getInstance()->setViewHeightInPixels( height );
02114 if (mWindow->getFullscreen())
02115 {
02116
02117 LLViewerCamera::getInstance()->setAspect( getDisplayAspectRatio() );
02118 }
02119 else
02120 {
02121 LLViewerCamera::getInstance()->setAspect( width / (F32) height);
02122 }
02123 }
02124
02125
02126 mWindowRect.mRight = mWindowRect.mLeft + width;
02127 mWindowRect.mTop = mWindowRect.mBottom + height;
02128 calcDisplayScale();
02129
02130 BOOL display_scale_changed = mDisplayScale != LLUI::sGLScaleFactor;
02131 LLUI::setScaleFactor(mDisplayScale);
02132
02133
02134 mVirtualWindowRect.mRight = mVirtualWindowRect.mLeft + llround((F32)width / mDisplayScale.mV[VX]);
02135 mVirtualWindowRect.mTop = mVirtualWindowRect.mBottom + llround((F32)height / mDisplayScale.mV[VY]);
02136
02137 setupViewport();
02138
02139
02140
02141 LLView::sForceReshape = display_scale_changed;
02142 mRootView->reshape(llceil((F32)width / mDisplayScale.mV[VX]), llceil((F32)height / mDisplayScale.mV[VY]));
02143 LLView::sForceReshape = FALSE;
02144
02145
02146 if (display_scale_changed)
02147 {
02148 LLHUDText::reshape();
02149 }
02150
02151 sendShapeToSim();
02152
02153
02154
02155 gSavedSettings.setBOOL("FullScreen", mWantFullscreen);
02156
02157
02158 if (mWindow->getFullscreen())
02159 {
02160 gSavedSettings.setS32("FullScreenWidth", width);
02161 gSavedSettings.setS32("FullScreenHeight", height);
02162 }
02163 else
02164 {
02165
02166 BOOL maximized = mWindow->getMaximized();
02167 gSavedSettings.setBOOL("WindowMaximized", maximized);
02168
02169 LLCoordScreen window_size;
02170 if (!maximized
02171 && mWindow->getSize(&window_size))
02172 {
02173 gSavedSettings.setS32("WindowWidth", window_size.mX);
02174 gSavedSettings.setS32("WindowHeight", window_size.mY);
02175 }
02176 }
02177
02178 LLViewerStats::getInstance()->setStat(LLViewerStats::ST_WINDOW_WIDTH, (F64)width);
02179 LLViewerStats::getInstance()->setStat(LLViewerStats::ST_WINDOW_HEIGHT, (F64)height);
02180 gResizeScreenTexture = TRUE;
02181 }
02182 }
02183
02184
02185
02186 void LLViewerWindow::setNormalControlsVisible( BOOL visible )
02187 {
02188 if ( gBottomPanel )
02189 {
02190 gBottomPanel->setVisible( visible );
02191 gBottomPanel->setEnabled( visible );
02192 }
02193
02194 if ( gMenuBarView )
02195 {
02196 gMenuBarView->setVisible( visible );
02197 gMenuBarView->setEnabled( visible );
02198
02199
02200 setMenuBackgroundColor(gAgent.getGodLevel() > GOD_NOT,
02201 LLAppViewer::instance()->isInProductionGrid());
02202 }
02203
02204 if ( gStatusBar )
02205 {
02206 gStatusBar->setVisible( visible );
02207 gStatusBar->setEnabled( visible );
02208 }
02209 }
02210
02211 void LLViewerWindow::setMenuBackgroundColor(bool god_mode, bool dev_grid)
02212 {
02213 LLString::format_map_t args;
02214 LLColor4 new_bg_color;
02215
02216 if(god_mode && LLAppViewer::instance()->isInProductionGrid())
02217 {
02218 new_bg_color = gColors.getColor( "MenuBarGodBgColor" );
02219 }
02220 else if(god_mode && !LLAppViewer::instance()->isInProductionGrid())
02221 {
02222 new_bg_color = gColors.getColor( "MenuNonProductionGodBgColor" );
02223 }
02224 else if(!god_mode && !LLAppViewer::instance()->isInProductionGrid())
02225 {
02226 new_bg_color = gColors.getColor( "MenuNonProductionBgColor" );
02227 }
02228 else
02229 {
02230 new_bg_color = gColors.getColor( "MenuBarBgColor" );
02231 }
02232
02233 if(gMenuBarView)
02234 {
02235 gMenuBarView->setBackgroundColor( new_bg_color );
02236 }
02237
02238 if(gStatusBar)
02239 {
02240 gStatusBar->setBackgroundColor( new_bg_color );
02241 }
02242 }
02243
02244 void LLViewerWindow::drawDebugText()
02245 {
02246 gGL.color4f(1,1,1,1);
02247 gGL.pushMatrix();
02248 {
02249
02250 glScalef(mDisplayScale.mV[VX], mDisplayScale.mV[VY], 1.f);
02251 mDebugText->draw();
02252 }
02253 gGL.popMatrix();
02254 gGL.flush();
02255 }
02256
02257 void LLViewerWindow::draw()
02258 {
02259
02260 #if LL_DEBUG
02261 LLView::sIsDrawing = TRUE;
02262 #endif
02263 stop_glerror();
02264
02265 LLUI::setLineWidth(1.f);
02266
02267 LLAlertInfo alert;
02268 while (LLPanel::nextAlert(alert))
02269 {
02270 alertXml(alert.mLabel, alert.mArgs);
02271 }
02272
02273 LLUI::setLineWidth(1.f);
02274
02275 glMatrixMode(GL_MODELVIEW);
02276
02277 glLoadIdentity();
02278
02279
02280
02281
02282 if (gSavedSettings.getBOOL("DisplayTimecode"))
02283 {
02284
02285 char text[256];
02286
02287 glLoadIdentity();
02288
02289 microsecondsToTimecodeString(gFrameTime,text);
02290 const LLFontGL* font = LLResMgr::getInstance()->getRes( LLFONT_SANSSERIF );
02291 font->renderUTF8(text, 0,
02292 llround((getWindowWidth()/2)-100.f),
02293 llround((getWindowHeight()-60.f)),
02294 LLColor4( 1.f, 1.f, 1.f, 1.f ),
02295 LLFontGL::LEFT, LLFontGL::TOP);
02296 }
02297
02298
02299
02300
02301 gGL.pushMatrix();
02302 {
02303
02304 glScalef(mDisplayScale.mV[VX], mDisplayScale.mV[VY], 1.f);
02305
02306 LLVector2 old_scale_factor = LLUI::sGLScaleFactor;
02307
02308 F32 zoom_factor = LLViewerCamera::getInstance()->getZoomFactor();
02309 S16 sub_region = LLViewerCamera::getInstance()->getZoomSubRegion();
02310 if (zoom_factor > 1.f)
02311 {
02312
02313 int pos_y = sub_region / llceil(zoom_factor);
02314 int pos_x = sub_region - (pos_y*llceil(zoom_factor));
02315
02316 glTranslatef((F32)getWindowWidth() * -(F32)pos_x,
02317 (F32)getWindowHeight() * -(F32)pos_y,
02318 0.f);
02319 glScalef(zoom_factor, zoom_factor, 1.f);
02320 LLUI::sGLScaleFactor *= zoom_factor;
02321 }
02322
02323
02324 LLToolMgr::getInstance()->getCurrentTool()->draw();
02325
02326 if( gAgent.cameraMouselook() )
02327 {
02328 drawMouselookInstructions();
02329 stop_glerror();
02330 }
02331
02332
02333
02334 mRootView->draw();
02335
02336
02337 LLUICtrl* top_ctrl = gFocusMgr.getTopCtrl();
02338 if (top_ctrl && top_ctrl->getVisible())
02339 {
02340 S32 screen_x, screen_y;
02341 top_ctrl->localPointToScreen(0, 0, &screen_x, &screen_y);
02342
02343 glMatrixMode(GL_MODELVIEW);
02344 LLUI::pushMatrix();
02345 LLUI::translate( (F32) screen_x, (F32) screen_y, 0.f);
02346 top_ctrl->draw();
02347 LLUI::popMatrix();
02348 }
02349
02350
02351
02352
02353 if( mToolTip && mToolTip->getVisible() )
02354 {
02355 glMatrixMode(GL_MODELVIEW);
02356 LLUI::pushMatrix();
02357 {
02358 S32 tip_height = mToolTip->getRect().getHeight();
02359
02360 S32 screen_x, screen_y;
02361 mToolTip->localPointToScreen(0, -24 - tip_height,
02362 &screen_x, &screen_y);
02363
02364
02365
02366 if (screen_y < tip_height)
02367 {
02368 mToolTip->localPointToScreen(0, 0, &screen_x, &screen_y);
02369 }
02370 LLUI::translate( (F32) screen_x, (F32) screen_y, 0);
02371 mToolTip->draw();
02372 }
02373 LLUI::popMatrix();
02374 }
02375
02376 if( gShowOverlayTitle && !mOverlayTitle.empty() )
02377 {
02378
02379 const S32 DIST_FROM_TOP = 20;
02380 LLFontGL::sSansSerifBig->renderUTF8(
02381 mOverlayTitle, 0,
02382 llround( getWindowWidth() * 0.5f),
02383 getWindowHeight() - DIST_FROM_TOP,
02384 LLColor4(1, 1, 1, 0.4f),
02385 LLFontGL::HCENTER, LLFontGL::TOP);
02386 }
02387
02388 LLUI::sGLScaleFactor = old_scale_factor;
02389 }
02390 gGL.popMatrix();
02391
02392 #if LL_DEBUG
02393 LLView::sIsDrawing = FALSE;
02394 #endif
02395 }
02396
02397
02398 BOOL LLViewerWindow::handleKey(KEY key, MASK mask)
02399 {
02400 if (gFocusMgr.getKeyboardFocus()
02401 && !(mask & (MASK_CONTROL | MASK_ALT))
02402 && !gFocusMgr.getKeystrokesOnly())
02403 {
02404
02405
02406 if (key < 0x80)
02407 {
02408
02409 return gFocusMgr.childHasKeyboardFocus(mRootView);
02410 }
02411 }
02412
02413
02414 if (LLView::sEditingUI)
02415 {
02416 if (LLFloaterEditUI::processKeystroke(key, mask))
02417 {
02418 return TRUE;
02419 }
02420 }
02421
02422
02423 if(mToolTip )
02424 {
02425 mToolTipBlocked = TRUE;
02426 mToolTip->setVisible( FALSE );
02427 }
02428
02429
02430 if (gHoverView)
02431 {
02432 gHoverView->cancelHover();
02433
02434 gHoverView->setTyping(TRUE);
02435 }
02436
02437
02438 if ((MASK_ALT & mask) &&
02439 (MASK_CONTROL & mask) &&
02440 ('D' == key || 'd' == key))
02441 {
02442 toggle_debug_menus(NULL);
02443 }
02444
02445
02446 if ((mask == (MASK_SHIFT | MASK_CONTROL)) &&
02447 ('G' == key || 'g' == key))
02448 {
02449 if (LLStartUp::getStartupState() < STATE_LOGIN_CLEANUP)
02450 {
02451 BOOL visible = ! gSavedSettings.getBOOL("ForceShowGrid");
02452 gSavedSettings.setBOOL("ForceShowGrid", visible);
02453
02454
02455 LLPanelLogin::refreshLocation( false );
02456 }
02457 }
02458
02459
02460 if ((MASK_SHIFT & mask)
02461 && (MASK_ALT & mask)
02462 && (MASK_CONTROL & mask)
02463 && ('H' == key || 'h' == key))
02464 {
02465 trigger_hippo_bug(NULL);
02466 }
02467
02468
02469 if (key == KEY_ESCAPE && mask == MASK_NONE)
02470 {
02471 if (gMenuHolder && gMenuHolder->hideMenus())
02472 {
02473 return TRUE;
02474 }
02475
02476
02477 if(LLMenuGL::getKeyboardMode())
02478 LLMenuGL::setKeyboardMode(FALSE);
02479
02480 if (gFocusMgr.getTopCtrl())
02481 {
02482 gFocusMgr.setTopCtrl(NULL);
02483 return TRUE;
02484 }
02485
02486
02487
02488
02489
02490
02491
02492
02493 }
02494
02495
02496 if (gMenuBarView && gMenuBarView->handleKey(key, mask, TRUE))
02497 {
02498 return TRUE;
02499 }
02500
02501 if (gLoginMenuBarView && gLoginMenuBarView->handleKey(key, mask, TRUE))
02502 {
02503 return TRUE;
02504 }
02505
02506
02507 LLUICtrl* keyboard_focus = gFocusMgr.getKeyboardFocus();
02508 if( keyboard_focus )
02509 {
02510
02511 if (gChatBar && gChatBar->inputEditorHasFocus())
02512 {
02513 if (gChatBar->getCurrentChat().empty() || gSavedSettings.getBOOL("ArrowKeysMoveAvatar"))
02514 {
02515 switch(key)
02516 {
02517 case KEY_LEFT:
02518 case KEY_RIGHT:
02519 case KEY_UP:
02520
02521 if( MASK_CONTROL == mask )
02522 {
02523 break;
02524 }
02525 case KEY_DOWN:
02526
02527 if( MASK_CONTROL == mask )
02528 {
02529 break;
02530 }
02531 case KEY_PAGE_UP:
02532 case KEY_PAGE_DOWN:
02533 case KEY_HOME:
02534
02535 return FALSE;
02536 default:
02537 break;
02538 }
02539 }
02540 }
02541
02542 if (keyboard_focus->handleKey(key, mask, FALSE))
02543 {
02544 return TRUE;
02545 }
02546 }
02547
02548 if( LLToolMgr::getInstance()->getCurrentTool()->handleKey(key, mask) )
02549 {
02550 return TRUE;
02551 }
02552
02553
02554 if (gGestureManager.triggerGesture(key, mask))
02555 {
02556 return TRUE;
02557 }
02558
02559
02560
02561 if (gGestureList.trigger(key, mask))
02562 {
02563 return TRUE;
02564 }
02565
02566
02567
02568
02569
02570
02571
02572
02573
02574
02575
02576
02577
02578
02579 if (key == KEY_TAB)
02580 {
02581
02582 if (mask & MASK_CONTROL || gFocusMgr.getKeyboardFocus() == NULL)
02583 {
02584 if (gMenuHolder) gMenuHolder->hideMenus();
02585
02586
02587 gFloaterView->setCycleMode((mask & MASK_CONTROL) != 0);
02588
02589
02590 if (mask & MASK_SHIFT)
02591 {
02592 mRootView->focusPrevRoot();
02593 }
02594 else
02595 {
02596 mRootView->focusNextRoot();
02597 }
02598 return TRUE;
02599 }
02600 }
02601
02602
02603 if (gMenuBarView && gMenuBarView->handleAcceleratorKey(key, mask))
02604 {
02605 return TRUE;
02606 }
02607
02608
02609 if (gLoginMenuBarView && gLoginMenuBarView->handleAcceleratorKey(key, mask))
02610 {
02611 return TRUE;
02612 }
02613
02614
02615 return gFocusMgr.childHasKeyboardFocus(mRootView)
02616 || LLMenuGL::getKeyboardMode()
02617 || (gMenuBarView && gMenuBarView->getHighlightedItem() && gMenuBarView->getHighlightedItem()->isActive());
02618 }
02619
02620
02621 BOOL LLViewerWindow::handleUnicodeChar(llwchar uni_char, MASK mask)
02622 {
02623
02624
02625
02626
02627
02628 if ((uni_char == 13 && mask != MASK_CONTROL)
02629 || (uni_char == 3 && mask == MASK_NONE))
02630 {
02631 return gViewerKeyboard.handleKey(KEY_RETURN, mask, gKeyboard->getKeyRepeated(KEY_RETURN));
02632 }
02633
02634
02635 if (gMenuBarView && gMenuBarView->handleUnicodeChar(uni_char, TRUE))
02636 {
02637 return TRUE;
02638 }
02639
02640
02641 LLView* keyboard_focus = gFocusMgr.getKeyboardFocus();
02642 if( keyboard_focus )
02643 {
02644 if (keyboard_focus->handleUnicodeChar(uni_char, FALSE))
02645 {
02646 return TRUE;
02647 }
02648
02650
02651
02652
02653
02654
02655
02656 return TRUE;
02657 }
02658
02659 return FALSE;
02660 }
02661
02662
02663 void LLViewerWindow::handleScrollWheel(S32 clicks)
02664 {
02665 LLView::sMouseHandlerMessage = "";
02666
02667 gMouseIdleTimer.reset();
02668
02669
02670 if( mToolTip )
02671 {
02672 mToolTip->setVisible( FALSE );
02673 }
02674
02675 LLMouseHandler* mouse_captor = gFocusMgr.getMouseCapture();
02676 if( mouse_captor )
02677 {
02678 S32 local_x;
02679 S32 local_y;
02680 mouse_captor->screenPointToLocal( mCurrentMousePoint.mX, mCurrentMousePoint.mY, &local_x, &local_y );
02681 mouse_captor->handleScrollWheel(local_x, local_y, clicks);
02682 if (LLView::sDebugMouseHandling)
02683 {
02684 llinfos << "Scroll Wheel handled by captor " << mouse_captor->getName() << llendl;
02685 }
02686 return;
02687 }
02688
02689 LLUICtrl* top_ctrl = gFocusMgr.getTopCtrl();
02690 if (top_ctrl)
02691 {
02692 S32 local_x;
02693 S32 local_y;
02694 top_ctrl->screenPointToLocal( mCurrentMousePoint.mX, mCurrentMousePoint.mY, &local_x, &local_y );
02695 if (top_ctrl->handleScrollWheel(local_x, local_y, clicks)) return;
02696 }
02697
02698 if (mRootView->handleScrollWheel(mCurrentMousePoint.mX, mCurrentMousePoint.mY, clicks) )
02699 {
02700 if (LLView::sDebugMouseHandling)
02701 {
02702 llinfos << "Scroll Wheel" << LLView::sMouseHandlerMessage << llendl;
02703 }
02704 return;
02705 }
02706 else if (LLView::sDebugMouseHandling)
02707 {
02708 llinfos << "Scroll Wheel not handled by view" << llendl;
02709 }
02710
02711
02712 gAgent.handleScrollWheel(clicks);
02713
02714 return;
02715 }
02716
02717 void LLViewerWindow::moveCursorToCenter()
02718 {
02719 S32 x = mVirtualWindowRect.getWidth() / 2;
02720 S32 y = mVirtualWindowRect.getHeight() / 2;
02721
02722
02723 mCurrentMousePoint.set(x,y);
02724 mLastMousePoint.set(x,y);
02725 mCurrentMouseDelta.set(0,0);
02726
02727 LLUI::setCursorPositionScreen(x, y);
02728 }
02729
02731
02732
02733
02734
02735
02736
02737 BOOL LLViewerWindow::handlePerFrameHover()
02738 {
02739 static std::string last_handle_msg;
02740
02741 LLView::sMouseHandlerMessage = "";
02742
02743
02744 LLCoordWindow mouse_pos;
02745 mWindow->getCursorPosition(&mouse_pos);
02746 if (mouse_pos.mX < 0 ||
02747 mouse_pos.mY < 0 ||
02748 mouse_pos.mX > mWindowRect.getWidth() ||
02749 mouse_pos.mY > mWindowRect.getHeight())
02750 {
02751 mMouseInWindow = FALSE;
02752 }
02753 else
02754 {
02755 mMouseInWindow = TRUE;
02756 }
02757
02758 S32 dx = lltrunc((F32) (mCurrentMousePoint.mX - mLastMousePoint.mX) * LLUI::sGLScaleFactor.mV[VX]);
02759 S32 dy = lltrunc((F32) (mCurrentMousePoint.mY - mLastMousePoint.mY) * LLUI::sGLScaleFactor.mV[VY]);
02760
02761 LLVector2 mouse_vel;
02762
02763 if (gSavedSettings.getBOOL("MouseSmooth"))
02764 {
02765 static F32 fdx = 0.f;
02766 static F32 fdy = 0.f;
02767
02768 F32 amount = 16.f;
02769 fdx = fdx + ((F32) dx - fdx) * llmin(gFrameIntervalSeconds*amount,1.f);
02770 fdy = fdy + ((F32) dy - fdy) * llmin(gFrameIntervalSeconds*amount,1.f);
02771
02772 mCurrentMouseDelta.set(llround(fdx), llround(fdy));
02773 mouse_vel.setVec(fdx,fdy);
02774 }
02775 else
02776 {
02777 mCurrentMouseDelta.set(dx, dy);
02778 mouse_vel.setVec((F32) dx, (F32) dy);
02779 }
02780
02781 mMouseVelocityStat.addValue(mouse_vel.magVec());
02782
02783 if (gNoRender)
02784 {
02785 return TRUE;
02786 }
02787
02788 S32 x = mCurrentMousePoint.mX;
02789 S32 y = mCurrentMousePoint.mY;
02790 MASK mask = gKeyboard->currentMask(TRUE);
02791
02792
02793 LLUICtrl* cur_focus = gFocusMgr.getKeyboardFocus();
02794 if (cur_focus)
02795 {
02796 if (!cur_focus->isInVisibleChain() || !cur_focus->isInEnabledChain())
02797 {
02798 gFocusMgr.releaseFocusIfNeeded(cur_focus);
02799
02800 LLUICtrl* parent = cur_focus->getParentUICtrl();
02801 const LLUICtrl* focus_root = cur_focus->findRootMostFocusRoot();
02802 while(parent)
02803 {
02804 if (parent->isCtrl() &&
02805 (parent->hasTabStop() || parent == focus_root) &&
02806 !parent->getIsChrome() &&
02807 parent->isInVisibleChain() &&
02808 parent->isInEnabledChain())
02809 {
02810 if (!parent->focusFirstItem())
02811 {
02812 parent->setFocus(TRUE);
02813 }
02814 break;
02815 }
02816 parent = parent->getParentUICtrl();
02817 }
02818 }
02819 else if (cur_focus->isFocusRoot())
02820 {
02821
02822
02823 cur_focus->focusFirstItem();
02824 }
02825 }
02826
02827 gPipeline.sRenderProcessBeacons = FALSE;
02828 KEY key = gKeyboard->currentKey();
02829 if (((mask & MASK_CONTROL) && ('N' == key || 'n' == key)) || gSavedSettings.getBOOL("BeaconAlwaysOn"))
02830 {
02831 gPipeline.sRenderProcessBeacons = TRUE;
02832 }
02833
02834 BOOL handled = FALSE;
02835
02836 BOOL handled_by_top_ctrl = FALSE;
02837 LLUICtrl* top_ctrl = gFocusMgr.getTopCtrl();
02838
02839 LLMouseHandler* mouse_captor = gFocusMgr.getMouseCapture();
02840 if( mouse_captor )
02841 {
02842
02843 S32 local_x;
02844 S32 local_y;
02845 mouse_captor->screenPointToLocal( x, y, &local_x, &local_y );
02846 handled = mouse_captor->handleHover(local_x, local_y, mask);
02847 if (LLView::sDebugMouseHandling)
02848 {
02849 llinfos << "Hover handled by captor " << mouse_captor->getName() << llendl;
02850 }
02851
02852 if( !handled )
02853 {
02854 lldebugst(LLERR_USER_INPUT) << "hover not handled by mouse captor" << llendl;
02855 }
02856 }
02857 else
02858 {
02859 if (top_ctrl)
02860 {
02861 S32 local_x, local_y;
02862 top_ctrl->screenPointToLocal( x, y, &local_x, &local_y );
02863 handled = top_ctrl->pointInView(local_x, local_y) && top_ctrl->handleHover(local_x, local_y, mask);
02864 handled_by_top_ctrl = TRUE;
02865 }
02866
02867 if ( !handled )
02868 {
02869
02870
02871 if (mMouseInWindow && mRootView->handleHover(x, y, mask) )
02872 {
02873 if (LLView::sDebugMouseHandling && LLView::sMouseHandlerMessage != last_handle_msg)
02874 {
02875 last_handle_msg = LLView::sMouseHandlerMessage;
02876 llinfos << "Hover" << LLView::sMouseHandlerMessage << llendl;
02877 }
02878 handled = TRUE;
02879 }
02880 else if (LLView::sDebugMouseHandling)
02881 {
02882 if (last_handle_msg != "")
02883 {
02884 last_handle_msg = "";
02885 llinfos << "Hover not handled by view" << llendl;
02886 }
02887 }
02888 }
02889
02890 if( !handled )
02891 {
02892 lldebugst(LLERR_USER_INPUT) << "hover not handled by top view or root" << llendl;
02893 }
02894 }
02895
02896
02897
02898 LLTool *tool = NULL;
02899 if (gHoverView)
02900 {
02901 tool = LLToolMgr::getInstance()->getCurrentTool();
02902
02903 if(!handled && tool)
02904 {
02905 handled = tool->handleHover(x, y, mask);
02906
02907 if (!mWindow->isCursorHidden())
02908 {
02909 gHoverView->updateHover(tool);
02910 }
02911 }
02912 else
02913 {
02914
02915 gHoverView->cancelHover();
02916 }
02917
02918
02919
02920 mSuppressToolbox =
02921 (LLToolMgr::getInstance()->getBaseTool() == LLToolPie::getInstance()) &&
02922 (LLToolMgr::getInstance()->getCurrentTool() != LLToolPie::getInstance());
02923
02924 }
02925
02926
02927
02928 BOOL tool_tip_handled = FALSE;
02929 LLString tool_tip_msg;
02930 F32 tooltip_delay = gSavedSettings.getF32( "ToolTipDelay" );
02931
02932
02933 if ((mouse_captor && !mouse_captor->isView()) || LLUI::sShowXUINames)
02934 {
02935 tooltip_delay = gSavedSettings.getF32( "DragAndDropToolTipDelay" );
02936 }
02937 if( handled &&
02938 !mToolTipBlocked &&
02939 (gMouseIdleTimer.getElapsedTimeF32() > tooltip_delay) &&
02940 !mWindow->isCursorHidden() )
02941 {
02942 LLRect screen_sticky_rect;
02943
02944 if (mouse_captor)
02945 {
02946 S32 local_x, local_y;
02947 mouse_captor->screenPointToLocal( x, y, &local_x, &local_y );
02948 tool_tip_handled = mouse_captor->handleToolTip( local_x, local_y, tool_tip_msg, &screen_sticky_rect );
02949 }
02950 else if (handled_by_top_ctrl)
02951 {
02952 S32 local_x, local_y;
02953 top_ctrl->screenPointToLocal( x, y, &local_x, &local_y );
02954 tool_tip_handled = top_ctrl->handleToolTip( local_x, local_y, tool_tip_msg, &screen_sticky_rect );
02955 }
02956 else
02957 {
02958 tool_tip_handled = mRootView->handleToolTip(x, y, tool_tip_msg, &screen_sticky_rect );
02959 }
02960
02961 if( tool_tip_handled && !tool_tip_msg.empty() )
02962 {
02963 mToolTipStickyRect = screen_sticky_rect;
02964 mToolTip->setWrappedText( tool_tip_msg, 200 );
02965 mToolTip->reshapeToFitText();
02966 mToolTip->setOrigin( x, y );
02967 LLRect virtual_window_rect(0, getWindowHeight(), getWindowWidth(), 0);
02968 mToolTip->translateIntoRect( virtual_window_rect, FALSE );
02969 mToolTip->setVisible( TRUE );
02970 }
02971 }
02972
02973 if (tool && tool != gToolNull && tool != LLToolCompInspect::getInstance() && tool != LLToolDragAndDrop::getInstance() && !gSavedSettings.getBOOL("FreezeTime"))
02974 {
02975 LLMouseHandler *captor = gFocusMgr.getMouseCapture();
02976
02977
02978
02979 if (gFloaterTools->isMinimized() ||
02980 (tool != LLToolPie::getInstance()
02981 && tool != LLToolCompGun::getInstance()
02982 && !mSuppressToolbox
02983 && LLToolMgr::getInstance()->getCurrentToolset() != gFaceEditToolset
02984 && LLToolMgr::getInstance()->getCurrentToolset() != gMouselookToolset
02985 && (!captor || captor->isView()))
02986 )
02987 {
02988
02989 if (!gFloaterTools->getVisible())
02990 {
02991 gFloaterTools->open();
02992 }
02993
02994 LLCoordGL select_center_screen;
02995 gFloaterTools->updatePopup( select_center_screen, mask );
02996 }
02997 else
02998 {
02999 gFloaterTools->setVisible(FALSE);
03000 }
03001
03002
03003
03004
03005 }
03006 if (gToolBar)
03007 {
03008 gToolBar->refresh();
03009 }
03010
03011 if (gChatBar)
03012 {
03013 gChatBar->refresh();
03014 }
03015
03016 if (gOverlayBar)
03017 {
03018 gOverlayBar->refresh();
03019 }
03020
03021
03022 if (gOverlayBar && gNotifyBoxView && gConsole && gToolBar)
03023 {
03024 LLRect bar_rect(-1, STATUS_BAR_HEIGHT, getWindowWidth()+1, -1);
03025
03026 LLRect notify_box_rect = gNotifyBoxView->getRect();
03027 notify_box_rect.mBottom = bar_rect.mBottom;
03028 gNotifyBoxView->reshape(notify_box_rect.getWidth(), notify_box_rect.getHeight());
03029 gNotifyBoxView->setRect(notify_box_rect);
03030
03031
03032 LLRect floater_rect = gFloaterView->getRect();
03033 if (floater_rect.mBottom != bar_rect.mBottom+1)
03034 {
03035 floater_rect.mBottom = bar_rect.mBottom+1;
03036
03037 gFloaterView->reshapeFloater(floater_rect.getWidth(), floater_rect.getHeight(),
03038 TRUE, ADJUST_VERTICAL_NO);
03039 gFloaterView->setRect(floater_rect);
03040 }
03041
03042
03043 LLView* chatbar_and_buttons = gOverlayBar->getChild<LLView>("chatbar_and_buttons", TRUE);
03044
03045 if (chatbar_and_buttons && !chatbar_and_buttons->getLocalBoundingRect().isNull())
03046 {
03047
03048 S32 top, left;
03049 chatbar_and_buttons->localPointToOtherView(
03050 chatbar_and_buttons->getLocalBoundingRect().mLeft,
03051 chatbar_and_buttons->getLocalBoundingRect().mTop,
03052 &left,
03053 &top,
03054 gFloaterView);
03055 gFloaterView->setSnapOffsetBottom(top);
03056 }
03057 else if (gToolBar->getVisible())
03058 {
03059 S32 top, left;
03060 gToolBar->localPointToOtherView(
03061 gToolBar->getLocalBoundingRect().mLeft,
03062 gToolBar->getLocalBoundingRect().mTop,
03063 &left,
03064 &top,
03065 gFloaterView);
03066 gFloaterView->setSnapOffsetBottom(top);
03067 }
03068 else
03069 {
03070 gFloaterView->setSnapOffsetBottom(0);
03071 }
03072
03073
03074 LLRect console_rect = gConsole->getRect();
03075 console_rect.mBottom = gHUDView->getRect().mBottom + CONSOLE_BOTTOM_PAD;
03076 gConsole->reshape(console_rect.getWidth(), console_rect.getHeight());
03077 gConsole->setRect(console_rect);
03078 }
03079
03080 mLastMousePoint = mCurrentMousePoint;
03081
03082
03083 if (LLEditMenuHandler::gEditMenuHandler == NULL && LLSelectMgr::getInstance()->getSelection()->getObjectCount())
03084 {
03085 LLEditMenuHandler::gEditMenuHandler = LLSelectMgr::getInstance();
03086 }
03087
03088 if (gFloaterView->getCycleMode())
03089 {
03090
03091 gFloaterView->highlightFocusedFloater();
03092 gSnapshotFloaterView->highlightFocusedFloater();
03093 if ((gKeyboard->currentMask(TRUE) & MASK_CONTROL) == 0)
03094 {
03095
03096 gFloaterView->setCycleMode(FALSE);
03097
03098 gFloaterView->syncFloaterTabOrder();
03099 }
03100 else
03101 {
03102
03103 }
03104 }
03105 else
03106 {
03107
03108 gFloaterView->highlightFocusedFloater();
03109 gSnapshotFloaterView->highlightFocusedFloater();
03110
03111 gFloaterView->syncFloaterTabOrder();
03112 }
03113
03114 if (gSavedSettings.getBOOL("ChatBarStealsFocus")
03115 && gChatBar
03116 && gFocusMgr.getKeyboardFocus() == NULL
03117 && gChatBar->isInVisibleChain())
03118 {
03119 gChatBar->startChat(NULL);
03120 }
03121
03122
03123 if (LLModalDialog::activeCount() == 0)
03124 {
03125 LLViewerParcelMgr::getInstance()->deselectUnused();
03126 }
03127
03128 if (LLModalDialog::activeCount() == 0)
03129 {
03130 LLSelectMgr::getInstance()->deselectUnused();
03131 }
03132
03133 return handled;
03134 }
03135
03136
03137 void LLViewerWindow::saveLastMouse(const LLCoordGL &point)
03138 {
03139
03140
03141 if (point.mX < 0)
03142 {
03143 mCurrentMousePoint.mX = 0;
03144 }
03145 else if (point.mX > getWindowWidth())
03146 {
03147 mCurrentMousePoint.mX = getWindowWidth();
03148 }
03149 else
03150 {
03151 mCurrentMousePoint.mX = point.mX;
03152 }
03153
03154 if (point.mY < 0)
03155 {
03156 mCurrentMousePoint.mY = 0;
03157 }
03158 else if (point.mY > getWindowHeight() )
03159 {
03160 mCurrentMousePoint.mY = getWindowHeight();
03161 }
03162 else
03163 {
03164 mCurrentMousePoint.mY = point.mY;
03165 }
03166 }
03167
03168
03169
03170
03171
03172
03173
03174
03175 void LLViewerWindow::renderSelections( BOOL for_gl_pick, BOOL pick_parcel_walls, BOOL for_hud )
03176 {
03177 LLObjectSelectionHandle selection = LLSelectMgr::getInstance()->getSelection();
03178
03179 if (!for_hud && !for_gl_pick)
03180 {
03181
03182 LLSelectMgr::getInstance()->updateSilhouettes();
03183 }
03184
03185
03186 if (for_gl_pick)
03187 {
03188 if (pick_parcel_walls)
03189 {
03190 LLViewerParcelMgr::getInstance()->renderParcelCollision();
03191 }
03192 }
03193 else if (( for_hud && selection->getSelectType() == SELECT_TYPE_HUD) ||
03194 (!for_hud && selection->getSelectType() != SELECT_TYPE_HUD))
03195 {
03196 LLSelectMgr::getInstance()->renderSilhouettes(for_hud);
03197
03198 stop_glerror();
03199
03200
03201 if (selection->getSelectType() == SELECT_TYPE_HUD && LLSelectMgr::getInstance()->getSelection()->getObjectCount())
03202 {
03203 LLBBox hud_bbox = gAgent.getAvatarObject()->getHUDBBox();
03204
03205
03206 glMatrixMode(GL_PROJECTION);
03207 glPushMatrix();
03208 glLoadIdentity();
03209 F32 depth = llmax(1.f, hud_bbox.getExtentLocal().mV[VX] * 1.1f);
03210 glOrtho(-0.5f * LLViewerCamera::getInstance()->getAspect(), 0.5f * LLViewerCamera::getInstance()->getAspect(), -0.5f, 0.5f, 0.f, depth);
03211
03212 glMatrixMode(GL_MODELVIEW);
03213 glPushMatrix();
03214 glLoadIdentity();
03215 glLoadMatrixf(OGL_TO_CFR_ROTATION);
03216 glTranslatef(-hud_bbox.getCenterLocal().mV[VX] + (depth *0.5f), 0.f, 0.f);
03217 }
03218
03219
03220 if (LLSelectMgr::sRenderLightRadius && LLToolMgr::getInstance()->inEdit())
03221 {
03222 LLImageGL::unbindTexture(0);
03223 LLGLEnable gls_blend(GL_BLEND);
03224 LLGLEnable gls_cull(GL_CULL_FACE);
03225 LLGLDepthTest gls_depth(GL_TRUE, GL_FALSE);
03226 glMatrixMode(GL_MODELVIEW);
03227 glPushMatrix();
03228 if (selection->getSelectType() == SELECT_TYPE_HUD)
03229 {
03230 F32 zoom = gAgent.getAvatarObject()->mHUDCurZoom;
03231 glScalef(zoom, zoom, zoom);
03232 }
03233
03234 struct f : public LLSelectedObjectFunctor
03235 {
03236 virtual bool apply(LLViewerObject* object)
03237 {
03238 LLDrawable* drawable = object->mDrawable;
03239 if (drawable && drawable->isLight())
03240 {
03241 LLVOVolume* vovolume = drawable->getVOVolume();
03242 glPushMatrix();
03243
03244 LLVector3 center = drawable->getPositionAgent();
03245 glTranslatef(center[0], center[1], center[2]);
03246 F32 scale = vovolume->getLightRadius();
03247 glScalef(scale, scale, scale);
03248
03249 LLColor4 color(vovolume->getLightColor(), .5f);
03250 glColor4fv(color.mV);
03251
03252 F32 pixel_area = 100000.f;
03253
03254 gSphere.render(pixel_area);
03255
03256
03257 glCullFace(GL_FRONT);
03258 gSphere.render(pixel_area);
03259 glCullFace(GL_BACK);
03260
03261 glPopMatrix();
03262 }
03263 return true;
03264 }
03265 } func;
03266 LLSelectMgr::getInstance()->getSelection()->applyToObjects(&func);
03267
03268 glPopMatrix();
03269 }
03270
03271
03272
03273
03274
03275 LLTool* tool = LLToolMgr::getInstance()->getCurrentTool();
03276 if (tool)
03277 {
03278 if(tool->isAlwaysRendered())
03279 {
03280 tool->render();
03281 }
03282 else
03283 {
03284 if( !LLSelectMgr::getInstance()->getSelection()->isEmpty() )
03285 {
03286 BOOL moveable_object_selected = FALSE;
03287 BOOL all_selected_objects_move = TRUE;
03288 BOOL all_selected_objects_modify = TRUE;
03289 BOOL selecting_linked_set = !gSavedSettings.getBOOL("EditLinkedParts");
03290
03291 for (LLObjectSelection::iterator iter = LLSelectMgr::getInstance()->getSelection()->begin();
03292 iter != LLSelectMgr::getInstance()->getSelection()->end(); iter++)
03293 {
03294 LLSelectNode* nodep = *iter;
03295 LLViewerObject* object = nodep->getObject();
03296 BOOL this_object_movable = FALSE;
03297 if (object->permMove() && (object->permModify() || selecting_linked_set))
03298 {
03299 moveable_object_selected = TRUE;
03300 this_object_movable = TRUE;
03301 }
03302 all_selected_objects_move = all_selected_objects_move && this_object_movable;
03303 all_selected_objects_modify = all_selected_objects_modify && object->permModify();
03304 }
03305
03306 BOOL draw_handles = TRUE;
03307
03308 if (tool == LLToolCompTranslate::getInstance() && (!moveable_object_selected || !all_selected_objects_move))
03309 {
03310 draw_handles = FALSE;
03311 }
03312
03313 if (tool == LLToolCompRotate::getInstance() && (!moveable_object_selected || !all_selected_objects_move))
03314 {
03315 draw_handles = FALSE;
03316 }
03317
03318 if ( !all_selected_objects_modify && tool == LLToolCompScale::getInstance() )
03319 {
03320 draw_handles = FALSE;
03321 }
03322
03323 if( draw_handles )
03324 {
03325 tool->render();
03326 }
03327 }
03328 }
03329 if (selection->getSelectType() == SELECT_TYPE_HUD && selection->getObjectCount())
03330 {
03331 glMatrixMode(GL_PROJECTION);
03332 glPopMatrix();
03333
03334 glMatrixMode(GL_MODELVIEW);
03335 glPopMatrix();
03336 stop_glerror();
03337 }
03338 }
03339 }
03340 }
03341
03342
03343 LLVector3d LLViewerWindow::clickPointInWorldGlobal(S32 x, S32 y_from_bot, LLViewerObject* clicked_object) const
03344 {
03345
03346
03347 LLVector3 mouse_direction_global = mouseDirectionGlobal( x, y_from_bot );
03348
03349 LLVector3d relative_object = clicked_object->getPositionGlobal() - gAgent.getCameraPositionGlobal();
03350
03351
03352
03353 mouse_direction_global *= (F32) relative_object.magVec();
03354
03355 LLVector3d new_pos;
03356 new_pos.setVec(mouse_direction_global);
03357
03358 new_pos += gAgent.getCameraPositionGlobal();
03359
03360 return new_pos;
03361 }
03362
03363
03364 BOOL LLViewerWindow::clickPointOnSurfaceGlobal(const S32 x, const S32 y, LLViewerObject *objectp, LLVector3d &point_global) const
03365 {
03366 BOOL intersect = FALSE;
03367
03368
03369 if (!intersect)
03370 {
03371 point_global = clickPointInWorldGlobal(x, y, objectp);
03372 llinfos << "approx intersection at " << (objectp->getPositionGlobal() - point_global) << llendl;
03373 }
03374 else
03375 {
03376 llinfos << "good intersection at " << (objectp->getPositionGlobal() - point_global) << llendl;
03377 }
03378
03379 return intersect;
03380 }
03381
03382 void LLViewerWindow::hitObjectOrLandGlobalAsync(S32 x, S32 y_from_bot, MASK mask, void (*callback)(S32 x, S32 y, MASK mask), BOOL pick_transparent, BOOL pick_parcel_walls)
03383 {
03384 if (gNoRender)
03385 {
03386 return;
03387 }
03388
03389 render_ui_and_swap_if_needed();
03390 glClear(GL_DEPTH_BUFFER_BIT);
03391 gDisplaySwapBuffers = FALSE;
03392
03393 S32 scaled_x = llround((F32)x * mDisplayScale.mV[VX]);
03394 S32 scaled_y = llround((F32)y_from_bot * mDisplayScale.mV[VY]);
03395
03396 BOOL in_build_mode = gFloaterTools && gFloaterTools->getVisible();
03397 if (in_build_mode || LLDrawPoolAlpha::sShowDebugAlpha)
03398 {
03399
03400
03401 pick_transparent = TRUE;
03402 }
03403 gPickTransparent = pick_transparent;
03404
03405 gUseGLPick = FALSE;
03406 mPickCallback = callback;
03407
03408
03409 gLastHitPosGlobal.zeroVec();
03410 gLastHitObjectOffset.zeroVec();
03411 gLastHitObjectID.setNull();
03412 gLastHitObjectFace = -1;
03413
03414 gLastHitNonFloraPosGlobal.zeroVec();
03415 gLastHitNonFloraObjectOffset.zeroVec();
03416 gLastHitNonFloraObjectID.setNull();
03417 gLastHitNonFloraObjectFace = -1;
03418
03419 gLastHitParcelWall = FALSE;
03420
03421 LLCamera pick_camera;
03422 pick_camera.setOrigin(LLViewerCamera::getInstance()->getOrigin());
03423 pick_camera.setOriginAndLookAt(LLViewerCamera::getInstance()->getOrigin(),
03424 LLViewerCamera::getInstance()->getUpAxis(),
03425 LLViewerCamera::getInstance()->getOrigin() + mouseDirectionGlobal(x, y_from_bot));
03426 pick_camera.setView(0.5f*DEG_TO_RAD);
03427 pick_camera.setNear(LLViewerCamera::getInstance()->getNear());
03428 pick_camera.setFar(LLViewerCamera::getInstance()->getFar());
03429 pick_camera.setAspect(1.f);
03430
03431
03432
03433
03434 glMatrixMode(GL_MODELVIEW);
03435 glPushMatrix();
03436 glLoadIdentity();
03437
03438 glMatrixMode(GL_PROJECTION);
03439 glPushMatrix();
03440 glLoadIdentity();
03441
03442
03443
03444
03445 LLViewerCamera::getInstance()->setPerspective(FOR_SELECTION, scaled_x - (PICK_HALF_WIDTH + 2), scaled_y - (PICK_HALF_WIDTH + 2), PICK_DIAMETER + 4, PICK_DIAMETER + 4, FALSE);
03446
03447 gGLViewport[0] = scaled_x - (PICK_HALF_WIDTH + 2);
03448 gGLViewport[1] = scaled_y - (PICK_HALF_WIDTH + 2);
03449 gGLViewport[2] = PICK_DIAMETER + 4;
03450 gGLViewport[3] = PICK_DIAMETER + 4;
03451 glViewport(gGLViewport[0], gGLViewport[1], gGLViewport[2], gGLViewport[3]);
03452 LLViewerCamera::updateFrustumPlanes(pick_camera);
03453 stop_glerror();
03454
03455 glClearColor(0.f, 0.f, 0.f, 0.f);
03456 glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
03457
03458
03459
03460
03461 gObjectList.renderObjectsForSelect(pick_camera, pick_parcel_walls);
03462
03463 stop_glerror();
03464
03465
03466 glMatrixMode(GL_PROJECTION);
03467 glPopMatrix();
03468 glMatrixMode(GL_MODELVIEW);
03469 glPopMatrix();
03470
03471 setupViewport();
03472
03473 mPickPoint.set(x, y_from_bot);
03474 mPickOffset.set(0, 0);
03475 mPickMask = mask;
03476 mPickPending = TRUE;
03477
03478
03479 mWindow->delayInputProcessing();
03480 }
03481
03482 void LLViewerWindow::hitUIElementImmediate(S32 x, S32 y, void (*callback)(S32 x, S32 y, MASK mask))
03483 {
03484
03485
03486 if (gNoRender)
03487 {
03488 return;
03489 }
03490
03491 hitUIElementAsync(x, y, gKeyboard->currentMask(TRUE), NULL);
03492 performPick();
03493 if (callback)
03494 {
03495 callback(x, y, gKeyboard->currentMask(TRUE));
03496 }
03497 }
03498
03499
03500 void LLViewerWindow::hitUIElementAsync(S32 x, S32 y_from_bot, MASK mask, void (*callback)(S32 x, S32 y, MASK mask))
03501 {
03502 if (gNoRender)
03503 {
03504 return;
03505 }
03506
03507
03508
03509 gUseGLPick = FALSE;
03510 mPickCallback = callback;
03511
03512
03513 gLastHitUIElement = 0;
03514
03515 LLCamera pick_camera;
03516 pick_camera.setOrigin(LLViewerCamera::getInstance()->getOrigin());
03517 pick_camera.setOriginAndLookAt(LLViewerCamera::getInstance()->getOrigin(),
03518 LLViewerCamera::getInstance()->getUpAxis(),
03519 LLViewerCamera::getInstance()->getOrigin() + mouseDirectionGlobal(x, y_from_bot));
03520 pick_camera.setView(0.5f*DEG_TO_RAD);
03521 pick_camera.setNear(LLViewerCamera::getInstance()->getNear());
03522 pick_camera.setFar(LLViewerCamera::getInstance()->getFar());
03523 pick_camera.setAspect(1.f);
03524
03525
03526 glMatrixMode(GL_MODELVIEW);
03527 glPushMatrix();
03528 glLoadIdentity();
03529
03530 glMatrixMode(GL_PROJECTION);
03531 glPushMatrix();
03532 glLoadIdentity();
03533
03534
03535
03536
03537 setup2DRender();
03538 const LLVector2& display_scale = getDisplayScale();
03539 glScalef(display_scale.mV[VX], display_scale.mV[VY], 1.f);
03540
03541 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
03542
03543
03544 glViewport(x - (PICK_HALF_WIDTH + 2), y_from_bot - (PICK_HALF_WIDTH + 2), PICK_DIAMETER + 4, PICK_DIAMETER + 4);
03545 stop_glerror();
03546
03547 glClearColor(0.f, 0.f, 0.f, 0.f);
03548 glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
03549
03550
03551
03552
03553
03554 stop_glerror();
03555
03556
03557 glMatrixMode(GL_PROJECTION);
03558 glPopMatrix();
03559 glMatrixMode(GL_MODELVIEW);
03560 glPopMatrix();
03561
03562 setupViewport();
03563
03564 mPickPoint.set(x, y_from_bot);
03565 mPickOffset.set(0, 0);
03566 mPickMask = mask;
03567 mPickPending = TRUE;
03568 }
03569
03570 void LLViewerWindow::performPick()
03571 {
03572 if (gNoRender || !mPickPending)
03573 {
03574 return;
03575 }
03576
03577 mPickPending = FALSE;
03578 U32 te_offset = NO_FACE;
03579
03580
03581 LLCoordGL scaled_pick_point = mPickPoint;
03582 scaled_pick_point.mX = llclamp(llround((F32)mPickPoint.mX * mDisplayScale.mV[VX]), PICK_HALF_WIDTH, getWindowDisplayWidth() - PICK_HALF_WIDTH);
03583 scaled_pick_point.mY = llclamp(llround((F32)mPickPoint.mY * mDisplayScale.mV[VY]), PICK_HALF_WIDTH, getWindowDisplayHeight() - PICK_HALF_WIDTH);
03584
03585 glReadPixels(scaled_pick_point.mX - PICK_HALF_WIDTH, scaled_pick_point.mY - PICK_HALF_WIDTH, PICK_DIAMETER, PICK_DIAMETER, GL_RGBA, GL_UNSIGNED_BYTE, mPickBuffer);
03586
03587 S32 pixel_index = PICK_HALF_WIDTH * PICK_DIAMETER + PICK_HALF_WIDTH;
03588 S32 name = (U32)mPickBuffer[(pixel_index * 4) + 0] << 16 | (U32)mPickBuffer[(pixel_index * 4) + 1] << 8 | (U32)mPickBuffer[(pixel_index * 4) + 2];
03589 gLastPickAlpha = mPickBuffer[(pixel_index * 4) + 3];
03590
03591 if (name >= (S32)GL_NAME_UI_RESERVED && name < (S32)GL_NAME_INDEX_OFFSET)
03592 {
03593
03594 gLastHitUIElement = name;
03595 if (mPickCallback)
03596 {
03597 mPickCallback(mPickPoint.mX, mPickPoint.mY, mPickMask);
03598 }
03599 }
03600
03601
03602
03603 S32 x_offset = mPickPoint.mX - llround((F32)scaled_pick_point.mX / mDisplayScale.mV[VX]);
03604 S32 y_offset = mPickPoint.mY - llround((F32)scaled_pick_point.mY / mDisplayScale.mV[VY]);
03605
03606
03607
03608 if (!name)
03609 {
03610 S32 closest_distance = 10000;
03611
03612 for (S32 col = 0; col < PICK_DIAMETER; col++)
03613 {
03614 for (S32 row = 0; row < PICK_DIAMETER; row++)
03615 {
03616 S32 distance_squared = (llabs(col - x_offset - PICK_HALF_WIDTH) * llabs(col - x_offset - PICK_HALF_WIDTH)) + (llabs(row - y_offset - PICK_HALF_WIDTH) * llabs(row - y_offset - PICK_HALF_WIDTH));
03617 pixel_index = row * PICK_DIAMETER + col;
03618 S32 test_name = (U32)mPickBuffer[(pixel_index * 4) + 0] << 16 | (U32)mPickBuffer[(pixel_index * 4) + 1] << 8 | (U32)mPickBuffer[(pixel_index * 4) + 2];
03619 gLastPickAlpha = mPickBuffer[(pixel_index * 4) + 3];
03620 if (test_name && distance_squared < closest_distance)
03621 {
03622 closest_distance = distance_squared;
03623 name = test_name;
03624 gLastPickAlpha = mPickBuffer[(pixel_index * 4) + 3];
03625 mPickOffset.mX = col - PICK_HALF_WIDTH;
03626 mPickOffset.mY = row - PICK_HALF_WIDTH;
03627 }
03628 }
03629 }
03630 }
03631
03632 if (name)
03633 {
03634 mPickPoint.mX += llround((F32)mPickOffset.mX * mDisplayScale.mV[VX]);
03635 mPickPoint.mY += llround((F32)mPickOffset.mY * mDisplayScale.mV[VY]);
03636 }
03637
03638 if (gPickFaces)
03639 {
03640 te_offset = ((U32)name >> 20);
03641 name &= 0x000fffff;
03642
03643 }
03644
03645 LLViewerObject *objectp = NULL;
03646
03647
03648 LLViewerObject* nonflora_objectp = NULL;
03649 S32 nonflora_name = -1;
03650 S32 nonflora_te_offset = NO_FACE;
03651
03652 if (name == (S32)GL_NAME_PARCEL_WALL)
03653 {
03654 gLastHitParcelWall = TRUE;
03655 }
03656
03657 gLastHitHUDIcon = NULL;
03658
03659 objectp = gObjectList.getSelectedObject(name);
03660 if (objectp)
03661 {
03662 LLViewerObject* parent = (LLViewerObject*)(objectp->getParent());
03663 if (NULL == parent) {
03664
03665 parent = objectp;
03666 }
03667 if (objectp->mbCanSelect)
03668 {
03669 te_offset = (te_offset == 16) ? NO_FACE : te_offset;
03670
03671
03672 LLPCode pcode = objectp->getPCode();
03673 if( (LL_PCODE_LEGACY_GRASS != pcode) &&
03674 (LL_PCODE_LEGACY_TREE != pcode) &&
03675 (LL_PCODE_TREE_NEW != pcode))
03676 {
03677 nonflora_objectp = objectp;
03678 nonflora_name = name;
03679 nonflora_te_offset = te_offset;
03680 }
03681 }
03682 else
03683 {
03684
03685 }
03686 }
03687 else
03688 {
03689
03690 gLastHitHUDIcon = LLHUDIcon::handlePick(name);
03691 }
03692
03693 analyzeHit(
03694 mPickPoint.mX, mPickPoint.mY, objectp, te_offset,
03695 &gLastHitObjectID, &gLastHitObjectFace, &gLastHitPosGlobal, &gLastHitLand, &gLastHitUCoord, &gLastHitVCoord );
03696
03697 if (objectp && !gLastHitObjectID.isNull())
03698 {
03699 gLastHitObjectOffset = gAgent.calcFocusOffset(objectp, mPickPoint.mX, mPickPoint.mY);
03700 }
03701
03702 if( objectp == nonflora_objectp )
03703 {
03704 gLastHitNonFloraObjectID = gLastHitObjectID;
03705 gLastHitNonFloraObjectFace = gLastHitObjectFace;
03706 gLastHitNonFloraPosGlobal = gLastHitPosGlobal;
03707 gLastHitNonFloraObjectOffset= gLastHitObjectOffset;
03708 }
03709 else
03710 {
03711 analyzeHit( mPickPoint.mX, mPickPoint.mY, nonflora_objectp, nonflora_te_offset,
03712 &gLastHitNonFloraObjectID, &gLastHitNonFloraObjectFace, &gLastHitNonFloraPosGlobal,
03713 &gLastHitLand, &gLastHitUCoord, &gLastHitVCoord);
03714
03715 if( nonflora_objectp )
03716 {
03717 gLastHitNonFloraObjectOffset = gAgent.calcFocusOffset(nonflora_objectp, mPickPoint.mX, mPickPoint.mY);
03718 }
03719 }
03720
03721 if (mPickCallback)
03722 {
03723 mPickCallback(mPickPoint.mX, mPickPoint.mY, mPickMask);
03724 }
03725
03726 gPickFaces = FALSE;
03727 }
03728
03729
03730
03731 void LLViewerWindow::hitObjectOrLandGlobalImmediate(S32 x, S32 y_from_bot, void (*callback)(S32 x, S32 y, MASK mask), BOOL pick_transparent)
03732 {
03733 if (gNoRender)
03734 {
03735 return;
03736 }
03737
03738 hitObjectOrLandGlobalAsync(x, y_from_bot, gKeyboard->currentMask(TRUE), NULL, pick_transparent);
03739 performPick();
03740 if (callback)
03741 {
03742 callback(x, y_from_bot, gKeyboard->currentMask(TRUE));
03743 }
03744 }
03745
03746 LLViewerObject* LLViewerWindow::getObjectUnderCursor(const F32 depth)
03747 {
03748 S32 x = getCurrentMouseX();
03749 S32 y = getCurrentMouseY();
03750
03751 LLVector3 mouse_direction_global = mouseDirectionGlobal(x,y);
03752 LLVector3 camera_pos_global = LLViewerCamera::getInstance()->getOrigin();
03753 LLVector3 pick_end = camera_pos_global + mouse_direction_global * depth;
03754 LLVector3 collision_point;
03755 return gPipeline.pickObject(camera_pos_global, pick_end, collision_point);
03756 }
03757
03758 void LLViewerWindow::analyzeHit(
03759 S32 x,
03760 S32 y_from_bot,
03761 LLViewerObject* objectp,
03762 U32 te_offset,
03763 LLUUID* hit_object_id_p,
03764 S32* hit_face_p,
03765 LLVector3d* hit_pos_p,
03766 BOOL* hit_land,
03767 F32* hit_u_coord,
03768 F32* hit_v_coord)
03769 {
03770
03771 S32 face = -1;
03772
03773 if (te_offset != NO_FACE )
03774 {
03775 face = te_offset;
03776 }
03777
03778 *hit_land = FALSE;
03779
03780 if (objectp)
03781 {
03782 if( objectp->getPCode() == LLViewerObject::LL_VO_SURFACE_PATCH )
03783 {
03784
03785 *hit_land = TRUE;
03786
03787
03788 LLVector3d land_pos;
03789 if (mousePointOnLandGlobal(x, y_from_bot, &land_pos))
03790 {
03791 *hit_object_id_p = LLUUID::null;
03792 *hit_face_p = -1;
03793
03794
03795 *hit_pos_p = land_pos + LLVector3d(0.f, 0.f, 0.1f);
03796
03797 return;
03798 }
03799 else
03800 {
03801
03802
03803 }
03804 }
03805 else
03806 {
03807 *hit_object_id_p = objectp->mID;
03808 *hit_face_p = face;
03809
03810
03811 if (objectp->isAvatar())
03812 {
03813 *hit_pos_p = gAgent.getPosGlobalFromAgent(((LLVOAvatar*)objectp)->mPelvisp->getWorldPosition());
03814 }
03815 else if (objectp->mDrawable.notNull())
03816 {
03817 *hit_pos_p = gAgent.getPosGlobalFromAgent(objectp->getRenderPosition());
03818 }
03819 else
03820 {
03821
03822 *hit_pos_p = objectp->getPositionGlobal();
03823 }
03824
03825 if (gPickFaces && face > -1 &&
03826 objectp->mDrawable.notNull() && objectp->getPCode() == LL_PCODE_VOLUME &&
03827 face < objectp->mDrawable->getNumFaces())
03828 {
03829
03830
03831 S32 scaled_x = llround((F32)x * mDisplayScale.mV[VX]);
03832 S32 scaled_y = llround((F32)y_from_bot * mDisplayScale.mV[VY]);
03833 const S32 UV_PICK_WIDTH = 41;
03834 const S32 UV_PICK_HALF_WIDTH = (UV_PICK_WIDTH - 1) / 2;
03835 U8 uv_pick_buffer[UV_PICK_WIDTH * UV_PICK_WIDTH * 4];
03836 S32 pick_face = face;
03837 LLFace* facep = objectp->mDrawable->getFace(pick_face);
03838 LLViewerCamera::getInstance()->setPerspective(FOR_SELECTION, scaled_x - UV_PICK_HALF_WIDTH, scaled_y - UV_PICK_HALF_WIDTH, UV_PICK_WIDTH, UV_PICK_WIDTH, FALSE);
03839 glViewport(scaled_x - UV_PICK_HALF_WIDTH, scaled_y - UV_PICK_HALF_WIDTH, UV_PICK_WIDTH, UV_PICK_WIDTH);
03840 gPipeline.renderFaceForUVSelect(facep);
03841
03842 glReadPixels(scaled_x - UV_PICK_HALF_WIDTH, scaled_y - UV_PICK_HALF_WIDTH, UV_PICK_WIDTH, UV_PICK_WIDTH, GL_RGBA, GL_UNSIGNED_BYTE, uv_pick_buffer);
03843 U8* center_pixel = &uv_pick_buffer[4 * ((UV_PICK_WIDTH * UV_PICK_HALF_WIDTH) + UV_PICK_HALF_WIDTH + 1)];
03844 *hit_u_coord = (F32)((center_pixel[VGREEN] & 0xf) + (16.f * center_pixel[VRED])) / 4095.f;
03845 *hit_v_coord = (F32)((center_pixel[VGREEN] >> 4) + (16.f * center_pixel[VBLUE])) / 4095.f;
03846 }
03847 else
03848 {
03849 *hit_u_coord = 0.f;
03850 *hit_v_coord = 0.f;
03851 }
03852
03853
03854 return;
03855 }
03856 }
03857
03858
03859 *hit_object_id_p = LLUUID::null;
03860 *hit_face_p = -1;
03861 *hit_pos_p = LLVector3d::zero;
03862 *hit_u_coord = 0.f;
03863 *hit_v_coord = 0.f;
03864
03865 }
03866
03867
03868
03869 LLVector3 LLViewerWindow::mouseDirectionGlobal(const S32 x, const S32 y) const
03870 {
03871
03872 F32 fov = LLViewerCamera::getInstance()->getView();
03873
03874
03875 S32 height = getWindowHeight();
03876 S32 width = getWindowWidth();
03877
03878
03879 F32 distance = (height / 2.f) / (tan(fov / 2.f));
03880
03881
03882 F32 click_x = x - width / 2.f;
03883 F32 click_y = y - height / 2.f;
03884
03885
03886 LLVector3 mouse_vector = distance * LLViewerCamera::getInstance()->getAtAxis()
03887 - click_x * LLViewerCamera::getInstance()->getLeftAxis()
03888 + click_y * LLViewerCamera::getInstance()->getUpAxis();
03889
03890 mouse_vector.normVec();
03891
03892 return mouse_vector;
03893 }
03894
03895
03896
03897
03898 LLVector3 LLViewerWindow::mouseDirectionCamera(const S32 x, const S32 y) const
03899 {
03900
03901 F32 fov_height = LLViewerCamera::getInstance()->getView();
03902 F32 fov_width = fov_height * LLViewerCamera::getInstance()->getAspect();
03903
03904
03905 S32 height = getWindowHeight();
03906 S32 width = getWindowWidth();
03907
03908
03909 F32 click_x = (((F32)x / (F32)width) - 0.5f) * fov_width * -1.f;
03910 F32 click_y = (((F32)y / (F32)height) - 0.5f) * fov_height;
03911
03912
03913 LLVector3 mouse_vector = LLVector3(0.f, 0.f, -1.f);
03914 LLQuaternion mouse_rotate;
03915 mouse_rotate.setQuat(click_y, click_x, 0.f);
03916
03917 mouse_vector = mouse_vector * mouse_rotate;
03918
03919 mouse_vector = mouse_vector * (-1.f / mouse_vector.mV[VZ]);
03920
03921 return mouse_vector;
03922 }
03923
03924
03925
03926 BOOL LLViewerWindow::mousePointOnPlaneGlobal(LLVector3d& point, const S32 x, const S32 y,
03927 const LLVector3d &plane_point_global,
03928 const LLVector3 &plane_normal_global)
03929 {
03930 LLVector3d mouse_direction_global_d;
03931
03932 mouse_direction_global_d.setVec(mouseDirectionGlobal(x,y));
03933 LLVector3d plane_normal_global_d;
03934 plane_normal_global_d.setVec(plane_normal_global);
03935 F64 plane_mouse_dot = (plane_normal_global_d * mouse_direction_global_d);
03936 LLVector3d plane_origin_camera_rel = plane_point_global - gAgent.getCameraPositionGlobal();
03937 F64 mouse_look_at_scale = (plane_normal_global_d * plane_origin_camera_rel)
03938 / plane_mouse_dot;
03939 if (llabs(plane_mouse_dot) < 0.00001)
03940 {
03941
03942
03943
03944 LLVector3d plane_origin_dir = plane_origin_camera_rel;
03945 plane_origin_dir.normVec();
03946
03947 mouse_look_at_scale = plane_origin_camera_rel.magVec() / (plane_origin_dir * mouse_direction_global_d);
03948 }
03949
03950 point = gAgent.getCameraPositionGlobal() + mouse_look_at_scale * mouse_direction_global_d;
03951
03952 return mouse_look_at_scale > 0.0;
03953 }
03954
03955
03956
03957 BOOL LLViewerWindow::mousePointOnLandGlobal(const S32 x, const S32 y, LLVector3d *land_position_global)
03958 {
03959 LLVector3 mouse_direction_global = mouseDirectionGlobal(x,y);
03960 F32 mouse_dir_scale;
03961 BOOL hit_land = FALSE;
03962 LLViewerRegion *regionp;
03963 F32 land_z;
03964 const F32 FIRST_PASS_STEP = 1.0f;
03965 const F32 SECOND_PASS_STEP = 0.1f;
03966 LLVector3d camera_pos_global;
03967
03968 camera_pos_global = gAgent.getCameraPositionGlobal();
03969 LLVector3d probe_point_global;
03970 LLVector3 probe_point_region;
03971
03972
03973 for (mouse_dir_scale = FIRST_PASS_STEP; mouse_dir_scale < gAgent.mDrawDistance; mouse_dir_scale += FIRST_PASS_STEP)
03974 {
03975 LLVector3d mouse_direction_global_d;
03976 mouse_direction_global_d.setVec(mouse_direction_global * mouse_dir_scale);
03977 probe_point_global = camera_pos_global + mouse_direction_global_d;
03978
03979 regionp = LLWorld::getInstance()->resolveRegionGlobal(probe_point_region, probe_point_global);
03980
03981 if (!regionp)
03982 {
03983
03984 continue;
03985 }
03986
03987 S32 i = (S32) (probe_point_region.mV[VX]/regionp->getLand().getMetersPerGrid());
03988 S32 j = (S32) (probe_point_region.mV[VY]/regionp->getLand().getMetersPerGrid());
03989 S32 grids_per_edge = (S32) regionp->getLand().mGridsPerEdge;
03990 if ((i >= grids_per_edge) || (j >= grids_per_edge))
03991 {
03992
03993 continue;
03994 }
03995
03996 land_z = regionp->getLand().resolveHeightRegion(probe_point_region);
03997
03998
03999
04000 if (probe_point_region.mV[VZ] < land_z)
04001 {
04002
04003
04004
04005
04006 hit_land = TRUE;
04007 break;
04008 }
04009 }
04010
04011
04012 if (hit_land)
04013 {
04014
04015
04016
04017 F32 stop_mouse_dir_scale = mouse_dir_scale + FIRST_PASS_STEP;
04018
04019
04020 for ( mouse_dir_scale -= FIRST_PASS_STEP; mouse_dir_scale <= stop_mouse_dir_scale; mouse_dir_scale += SECOND_PASS_STEP)
04021 {
04022 LLVector3d mouse_direction_global_d;
04023 mouse_direction_global_d.setVec(mouse_direction_global * mouse_dir_scale);
04024 probe_point_global = camera_pos_global + mouse_direction_global_d;
04025
04026 regionp = LLWorld::getInstance()->resolveRegionGlobal(probe_point_region, probe_point_global);
04027
04028 if (!regionp)
04029 {
04030
04031 continue;
04032 }
04033
04034
04035
04036
04037
04038
04039
04040
04041
04042
04043
04044
04045 land_z = regionp->getLand().resolveHeightRegion(probe_point_region);
04046
04047
04048
04049 if (probe_point_region.mV[VZ] < land_z)
04050 {
04051
04052
04053 *land_position_global = probe_point_global;
04054 return TRUE;
04055 }
04056 }
04057 }
04058
04059 return FALSE;
04060 }
04061
04062
04063 BOOL LLViewerWindow::saveImageNumbered(LLImageRaw *raw, const LLString& extension_in)
04064 {
04065 if (! raw)
04066 {
04067 return FALSE;
04068 }
04069
04070 LLString extension(extension_in);
04071 if (extension.empty())
04072 {
04073 extension = (gSavedSettings.getBOOL("CompressSnapshotsToDisk")) ? ".j2c" : ".bmp";
04074 }
04075
04076 LLFilePicker::ESaveFilter pick_type;
04077 if (extension == ".j2c")
04078 pick_type = LLFilePicker::FFSAVE_J2C;
04079 else if (extension == ".bmp")
04080 pick_type = LLFilePicker::FFSAVE_BMP;
04081 else if (extension == ".tga")
04082 pick_type = LLFilePicker::FFSAVE_TGA;
04083 else
04084 pick_type = LLFilePicker::FFSAVE_ALL;
04085
04086
04087 if (strlen(sSnapshotDir) == 0)
04088 {
04089 LLString proposed_name( sSnapshotBaseName );
04090 proposed_name.append( extension );
04091
04092
04093 LLFilePicker& picker = LLFilePicker::instance();
04094 if (!picker.getSaveFile(pick_type, proposed_name.c_str()))
04095 {
04096
04097 return FALSE;
04098 }
04099
04100
04101 char directory[LL_MAX_PATH];
04102 strncpy(directory, picker.getFirstFile(), LL_MAX_PATH -1);
04103 directory[LL_MAX_PATH -1] = '\0';
04104
04105
04106 S32 length = strlen(directory);
04107 S32 index = length;
04108
04109
04110 index -= extension.length();
04111 if (index >= 0 && directory[index] == '.')
04112 {
04113 directory[index] = '\0';
04114 }
04115 else
04116 {
04117 index = length;
04118 }
04119
04120
04121 while (index >= 0 && directory[index] != gDirUtilp->getDirDelimiter()[0])
04122 {
04123 index--;
04124 }
04125
04126
04127 if (index >= 0)
04128 {
04129 if (index + 1 <= length)
04130 {
04131 strncpy(LLViewerWindow::sSnapshotBaseName, directory + index + 1, LL_MAX_PATH -1);
04132 LLViewerWindow::sSnapshotBaseName[LL_MAX_PATH -1] = '\0';
04133 }
04134
04135 index++;
04136 directory[index] = '\0';
04137 strncpy(LLViewerWindow::sSnapshotDir, directory, LL_MAX_PATH -1);
04138 LLViewerWindow::sSnapshotDir[LL_MAX_PATH -1] = '\0';
04139 }
04140 }
04141
04142
04143 LLString filepath;
04144 S32 i = 1;
04145 S32 err = 0;
04146
04147 do
04148 {
04149 filepath = sSnapshotDir;
04150 filepath += sSnapshotBaseName;
04151 filepath += llformat("_%.3d",i);
04152 filepath += extension;
04153
04154 struct stat stat_info;
04155 err = mWindow->stat( filepath.c_str(), &stat_info );
04156 i++;
04157 }
04158 while( -1 != err );
04159
04160 LLPointer<LLImageFormatted> formatted_image = LLImageFormatted::createFromExtension(extension);
04161 LLImageBase::setSizeOverride(TRUE);
04162 BOOL success = formatted_image->encode(raw, 0.0f);
04163 if( success )
04164 {
04165 success = formatted_image->save(filepath);
04166 }
04167 else
04168 {
04169 llwarns << "Unable to encode bmp snapshot" << llendl;
04170 }
04171 LLImageBase::setSizeOverride(FALSE);
04172
04173 return success;
04174 }
04175
04176
04177 static S32 BORDERHEIGHT = 0;
04178 static S32 BORDERWIDTH = 0;
04179
04180
04181 void LLViewerWindow::movieSize(S32 new_width, S32 new_height)
04182 {
04183 LLCoordScreen size;
04184 gViewerWindow->mWindow->getSize(&size);
04185 if ( (size.mX != new_width + BORDERWIDTH)
04186 ||(size.mY != new_height + BORDERHEIGHT))
04187 {
04188
04189 S32 x = gViewerWindow->getWindowDisplayWidth();
04190 S32 y = gViewerWindow->getWindowDisplayHeight();
04191 BORDERWIDTH = size.mX - x;
04192 BORDERHEIGHT = size.mY- y;
04193 LLCoordScreen new_size(new_width + BORDERWIDTH,
04194 new_height + BORDERHEIGHT);
04195 BOOL disable_sync = gSavedSettings.getBOOL("DisableVerticalSync");
04196 if (gViewerWindow->mWindow->getFullscreen())
04197 {
04198 gViewerWindow->changeDisplaySettings(FALSE,
04199 new_size,
04200 disable_sync,
04201 TRUE);
04202 }
04203 else
04204 {
04205 gViewerWindow->mWindow->setSize(new_size);
04206 }
04207 }
04208 }
04209
04210 BOOL LLViewerWindow::saveSnapshot( const LLString& filepath, S32 image_width, S32 image_height, BOOL show_ui, BOOL do_rebuild, ESnapshotType type)
04211 {
04212 llinfos << "Saving snapshot to: " << filepath << llendl;
04213
04214 LLPointer<LLImageRaw> raw = new LLImageRaw;
04215 BOOL success = rawSnapshot(raw, image_width, image_height, TRUE, FALSE, show_ui, do_rebuild);
04216
04217 if (success)
04218 {
04219 LLPointer<LLImageBMP> bmp_image = new LLImageBMP;
04220 success = bmp_image->encode(raw, 0.0f);
04221 if( success )
04222 {
04223 success = bmp_image->save(filepath);
04224 }
04225 else
04226 {
04227 llwarns << "Unable to encode bmp snapshot" << llendl;
04228 }
04229 }
04230 else
04231 {
04232 llwarns << "Unable to capture raw snapshot" << llendl;
04233 }
04234
04235 return success;
04236 }
04237
04238
04239 void LLViewerWindow::playSnapshotAnimAndSound()
04240 {
04241 gAgent.sendAnimationRequest(ANIM_AGENT_SNAPSHOT, ANIM_REQUEST_START);
04242 send_sound_trigger(LLUUID(gSavedSettings.getString("UISndSnapshot")), 1.0f);
04243 }
04244
04245 BOOL LLViewerWindow::thumbnailSnapshot(LLImageRaw *raw, S32 preview_width, S32 preview_height, BOOL show_ui, BOOL do_rebuild, ESnapshotType type)
04246 {
04247 if ((!raw) || preview_width < 10 || preview_height < 10)
04248 {
04249 return FALSE;
04250 }
04251
04252 if(gResizeScreenTexture)
04253 {
04254 return FALSE ;
04255 }
04256
04257 setCursor(UI_CURSOR_WAIT);
04258
04259
04260 BOOL prev_draw_ui = gPipeline.hasRenderDebugFeatureMask(LLPipeline::RENDER_DEBUG_FEATURE_UI);
04261
04262 if ( prev_draw_ui != show_ui)
04263 {
04264 LLPipeline::toggleRenderDebugFeature((void*)LLPipeline::RENDER_DEBUG_FEATURE_UI);
04265 }
04266
04267 BOOL hide_hud = !gSavedSettings.getBOOL("RenderHUDInSnapshot") && LLPipeline::sShowHUDAttachments;
04268 if (hide_hud)
04269 {
04270 LLPipeline::sShowHUDAttachments = FALSE;
04271 }
04272
04273 S32 render_name = gSavedSettings.getS32("RenderName");
04274 gSavedSettings.setS32("RenderName", 0);
04275 LLVOAvatar::updateFreezeCounter(1) ;
04276
04277 S32 w = preview_width ;
04278 S32 h = preview_height ;
04279 LLVector2 display_scale = mDisplayScale ;
04280 mDisplayScale.setVec((F32)w / mWindowRect.getWidth(), (F32)h / mWindowRect.getHeight()) ;
04281 LLRect window_rect = mWindowRect;
04282 mWindowRect.set(0, h, w, 0);
04283
04284 gDisplaySwapBuffers = FALSE;
04285 glClearColor(0.f, 0.f, 0.f, 0.f);
04286 glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
04287 setup3DRender();
04288 setupViewport();
04289
04290 LLFontGL::setFontDisplay(FALSE) ;
04291 LLHUDText::setDisplayText(FALSE) ;
04292 if (type == SNAPSHOT_TYPE_OBJECT_ID)
04293 {
04294 gPickTransparent = FALSE;
04295 gObjectList.renderObjectsForSelect(*LLViewerCamera::getInstance(), FALSE, FALSE);
04296 }
04297 else
04298 {
04299 display(do_rebuild, 1.0f, 0, TRUE);
04300 render_ui_and_swap();
04301 }
04302
04303 S32 glformat, gltype, glpixel_length ;
04304 if(SNAPSHOT_TYPE_DEPTH == type)
04305 {
04306 glpixel_length = 4 ;
04307 glformat = GL_DEPTH_COMPONENT ;
04308 gltype = GL_FLOAT ;
04309 }
04310 else
04311 {
04312 glpixel_length = 3 ;
04313 glformat = GL_RGB ;
04314 gltype = GL_UNSIGNED_BYTE ;
04315 }
04316
04317 raw->resize(w, h, glpixel_length);
04318 glReadPixels(0, 0, w, h, glformat, gltype, raw->getData());
04319
04320 if(SNAPSHOT_TYPE_DEPTH == type)
04321 {
04322 LLViewerCamera* camerap = LLViewerCamera::getInstance();
04323 F32 depth_conversion_factor_1 = (camerap->getFar() + camerap->getNear()) / (2.f * camerap->getFar() * camerap->getNear());
04324 F32 depth_conversion_factor_2 = (camerap->getFar() - camerap->getNear()) / (2.f * camerap->getFar() * camerap->getNear());
04325
04326
04327 for (S32 y = 0 ; y < h ; y++)
04328 {
04329 for(S32 x = 0 ; x < w ; x++)
04330 {
04331 S32 i = (w * y + x) << 2 ;
04332
04333 F32 depth_float_i = *(F32*)(raw->getData() + i);
04334
04335 F32 linear_depth_float = 1.f / (depth_conversion_factor_1 - (depth_float_i * depth_conversion_factor_2));
04336 U8 depth_byte = F32_to_U8(linear_depth_float, camerap->getNear(), camerap->getFar());
04337 *(raw->getData() + i + 0) = depth_byte;
04338 *(raw->getData() + i + 1) = depth_byte;
04339 *(raw->getData() + i + 2) = depth_byte;
04340 *(raw->getData() + i + 3) = 255;
04341 }
04342 }
04343 }
04344
04345 LLFontGL::setFontDisplay(TRUE) ;
04346 LLHUDText::setDisplayText(TRUE) ;
04347 mDisplayScale.setVec(display_scale) ;
04348 mWindowRect = window_rect;
04349 setup3DRender();
04350 setupViewport();
04351 gDisplaySwapBuffers = FALSE;
04352
04353
04354 if (!gPipeline.hasRenderDebugFeatureMask(LLPipeline::RENDER_DEBUG_FEATURE_UI))
04355 {
04356 LLPipeline::toggleRenderDebugFeature((void*)LLPipeline::RENDER_DEBUG_FEATURE_UI);
04357 }
04358
04359 if (hide_hud)
04360 {
04361 LLPipeline::sShowHUDAttachments = TRUE;
04362 }
04363
04364 setCursor(UI_CURSOR_ARROW);
04365
04366 if (do_rebuild)
04367 {
04368
04369
04370
04371
04372
04373 gPipeline.resetDrawOrders();
04374 }
04375
04376 gSavedSettings.setS32("RenderName", render_name);
04377
04378 return TRUE;
04379 }
04380
04381
04382 BOOL LLViewerWindow::rawSnapshot(LLImageRaw *raw, S32 image_width, S32 image_height,
04383 BOOL keep_window_aspect, BOOL is_texture, BOOL show_ui, BOOL do_rebuild, ESnapshotType type, S32 max_size)
04384 {
04385 if (!raw)
04386 {
04387 return FALSE;
04388 }
04389
04390
04391 render_ui_and_swap_if_needed();
04392 gDisplaySwapBuffers = FALSE;
04393
04394 glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
04395 setCursor(UI_CURSOR_WAIT);
04396
04397
04398 BOOL prev_draw_ui = gPipeline.hasRenderDebugFeatureMask(LLPipeline::RENDER_DEBUG_FEATURE_UI);
04399
04400 if ( prev_draw_ui != show_ui)
04401 {
04402 LLPipeline::toggleRenderDebugFeature((void*)LLPipeline::RENDER_DEBUG_FEATURE_UI);
04403 }
04404
04405 BOOL hide_hud = !gSavedSettings.getBOOL("RenderHUDInSnapshot") && LLPipeline::sShowHUDAttachments;
04406 if (hide_hud)
04407 {
04408 LLPipeline::sShowHUDAttachments = FALSE;
04409 }
04410
04411
04412
04413
04414 S32 snapshot_width = mWindowRect.getWidth();
04415 S32 snapshot_height = mWindowRect.getHeight();
04416
04417 S32 window_width = mWindowRect.getWidth();
04418 S32 window_height = mWindowRect.getHeight();
04419 LLRect window_rect = mWindowRect;
04420 BOOL use_fbo = FALSE;
04421
04422 F32 scale_factor = 1.0f ;
04423 if(!keep_window_aspect)
04424 {
04425 F32 ratio = llmin( (F32)window_width / image_width , (F32)window_height / image_height) ;
04426 snapshot_width = (S32)(ratio * image_width) ;
04427 snapshot_height = (S32)(ratio * image_height) ;
04428 scale_factor = llmax(1.0f, 1.0f / ratio) ;
04429 }
04430
04431 LLRenderTarget target;
04432 if (gGLManager.mHasFramebufferObject &&
04433 (image_width > window_width ||
04434 image_height > window_height) &&
04435 !show_ui &&
04436 keep_window_aspect)
04437 {
04438 GLint max_size = 0;
04439 glGetIntegerv(GL_MAX_RENDERBUFFER_SIZE_EXT, &max_size);
04440
04441 if (image_width <= max_size && image_height <= max_size)
04442 {
04443 use_fbo = TRUE;
04444
04445 snapshot_width = image_width;
04446 snapshot_height = image_height;
04447 target.allocate(snapshot_width, snapshot_height, GL_RGBA, TRUE, GL_TEXTURE_RECTANGLE_ARB, TRUE);
04448 window_width = snapshot_width;
04449 window_height = snapshot_height;
04450 scale_factor = 1.f;
04451 mWindowRect.set(0, 0, snapshot_width, snapshot_height);
04452 target.bindTarget();
04453 }
04454 else
04455 {
04456 F32 ratio = llmin( (F32)window_width / image_width , (F32)window_height / image_height) ;
04457 snapshot_width = (S32)(ratio * image_width) ;
04458 snapshot_height = (S32)(ratio * image_height) ;
04459 scale_factor = llmax(1.0f, 1.0f / ratio) ;
04460 }
04461 }
04462
04463 S32 buffer_x_offset = llfloor(((window_width - snapshot_width) * scale_factor) / 2.f);
04464 S32 buffer_y_offset = llfloor(((window_height - snapshot_height) * scale_factor) / 2.f);
04465
04466 S32 image_buffer_x = llfloor(snapshot_width*scale_factor) ;
04467 S32 image_buffer_y = llfloor(snapshot_height *scale_factor) ;
04468 if(image_buffer_x > max_size || image_buffer_y > max_size)
04469 {
04470 scale_factor *= llmin((F32)max_size / image_buffer_x, (F32)max_size / image_buffer_y) ;
04471 image_buffer_x = llfloor(snapshot_width*scale_factor) ;
04472 image_buffer_y = llfloor(snapshot_height *scale_factor) ;
04473 }
04474 raw->resize(image_buffer_x, image_buffer_y, type == SNAPSHOT_TYPE_DEPTH ? 4 : 3);
04475 if(raw->isBufferInvalid())
04476 {
04477 return FALSE ;
04478 }
04479
04480 BOOL high_res = scale_factor > 1.f;
04481 if (high_res)
04482 {
04483 send_agent_pause();
04484
04485 initFonts(scale_factor);
04486 LLHUDText::reshape();
04487 }
04488
04489 S32 output_buffer_offset_y = 0;
04490
04491 F32 depth_conversion_factor_1 = (LLViewerCamera::getInstance()->getFar() + LLViewerCamera::getInstance()->getNear()) / (2.f * LLViewerCamera::getInstance()->getFar() * LLViewerCamera::getInstance()->getNear());
04492 F32 depth_conversion_factor_2 = (LLViewerCamera::getInstance()->getFar() - LLViewerCamera::getInstance()->getNear()) / (2.f * LLViewerCamera::getInstance()->getFar() * LLViewerCamera::getInstance()->getNear());
04493
04494 for (int subimage_y = 0; subimage_y < scale_factor; ++subimage_y)
04495 {
04496 S32 subimage_y_offset = llclamp(buffer_y_offset - (subimage_y * window_height), 0, window_height);;
04497
04498 U32 read_height = llmax(0, (window_height - subimage_y_offset) -
04499 llmax(0, (window_height * (subimage_y + 1)) - (buffer_y_offset + raw->getHeight())));
04500
04501 S32 output_buffer_offset_x = 0;
04502 for (int subimage_x = 0; subimage_x < scale_factor; ++subimage_x)
04503 {
04504 gDisplaySwapBuffers = FALSE;
04505 if (type == SNAPSHOT_TYPE_OBJECT_ID)
04506 {
04507 glClearColor(0.f, 0.f, 0.f, 0.f);
04508 glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
04509
04510 LLViewerCamera::getInstance()->setZoomParameters(scale_factor, subimage_x+(subimage_y*llceil(scale_factor)));
04511 setup3DRender();
04512 setupViewport();
04513 BOOL first_time_through = (subimage_x + subimage_y == 0);
04514 gPickTransparent = FALSE;
04515 gObjectList.renderObjectsForSelect(*LLViewerCamera::getInstance(), FALSE, !first_time_through);
04516 }
04517 else
04518 {
04519 display(do_rebuild, scale_factor, subimage_x+(subimage_y*llceil(scale_factor)), use_fbo);
04520 render_ui_and_swap();
04521 }
04522
04523 S32 subimage_x_offset = llclamp(buffer_x_offset - (subimage_x * window_width), 0, window_width);
04524
04525 U32 read_width = llmax(0, (window_width - subimage_x_offset) -
04526 llmax(0, (window_width * (subimage_x + 1)) - (buffer_x_offset + raw->getWidth())));
04527 for(U32 out_y = 0; out_y < read_height ; out_y++)
04528 {
04529 if (type == SNAPSHOT_TYPE_OBJECT_ID || type == SNAPSHOT_TYPE_COLOR)
04530 {
04531 glReadPixels(
04532 subimage_x_offset, out_y + subimage_y_offset,
04533 read_width, 1,
04534 GL_RGB, GL_UNSIGNED_BYTE,
04535 raw->getData() +
04536 (
04537 (out_y * (raw->getWidth()))
04538 + (window_width * subimage_x)
04539 + (raw->getWidth() * window_height * subimage_y)
04540 - output_buffer_offset_x
04541 - (output_buffer_offset_y * (raw->getWidth()))
04542 ) * 3
04543 );
04544 }
04545 else
04546 {
04547 S32 output_buffer_offset = (
04548 (out_y * (raw->getWidth()))
04549 + (window_width * subimage_x)
04550 + (raw->getWidth() * window_height * subimage_y)
04551 - output_buffer_offset_x
04552 - (output_buffer_offset_y * (raw->getWidth()))
04553 ) * 4;
04554
04555 glReadPixels(
04556 subimage_x_offset, out_y + subimage_y_offset,
04557 read_width, 1,
04558 GL_DEPTH_COMPONENT, GL_FLOAT,
04559 raw->getData() + output_buffer_offset
04560 );
04561
04562 for (S32 i = output_buffer_offset; i < output_buffer_offset + (S32)read_width * 4; i += 4)
04563 {
04564 F32 depth_float = *(F32*)(raw->getData() + i);
04565
04566 F32 linear_depth_float = 1.f / (depth_conversion_factor_1 - (depth_float * depth_conversion_factor_2));
04567 U8 depth_byte = F32_to_U8(linear_depth_float, LLViewerCamera::getInstance()->getNear(), LLViewerCamera::getInstance()->getFar());
04568 *(raw->getData() + i + 0) = depth_byte;
04569 *(raw->getData() + i + 1) = depth_byte;
04570 *(raw->getData() + i + 2) = depth_byte;
04571 *(raw->getData() + i + 3) = 255;
04572 }
04573 }
04574 }
04575 output_buffer_offset_x += subimage_x_offset;
04576 stop_glerror();
04577 }
04578 output_buffer_offset_y += subimage_y_offset;
04579 }
04580
04581 if (use_fbo)
04582 {
04583 mWindowRect = window_rect;
04584 target.flush();
04585 glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
04586 }
04587 gDisplaySwapBuffers = FALSE;
04588
04589
04590 if (!gPipeline.hasRenderDebugFeatureMask(LLPipeline::RENDER_DEBUG_FEATURE_UI))
04591 {
04592 LLPipeline::toggleRenderDebugFeature((void*)LLPipeline::RENDER_DEBUG_FEATURE_UI);
04593 }
04594
04595 if (hide_hud)
04596 {
04597 LLPipeline::sShowHUDAttachments = TRUE;
04598 }
04599
04600 if (high_res)
04601 {
04602 initFonts(1.f);
04603 LLHUDText::reshape();
04604 }
04605
04606
04607
04608 image_width += (image_width * (type == SNAPSHOT_TYPE_DEPTH ? 4 : 3)) % 4 ;
04609
04610
04611 if(llabs(image_width - image_buffer_x) > 4 || llabs(image_height - image_buffer_y) > 4)
04612 {
04613 raw->scale( image_width, image_height );
04614 }
04615 else if(image_width != image_buffer_x || image_height != image_buffer_y)
04616 {
04617 raw->scale( image_width, image_height, FALSE );
04618 }
04619
04620
04621 setCursor(UI_CURSOR_ARROW);
04622
04623 if (do_rebuild)
04624 {
04625
04626
04627
04628
04629
04630 gPipeline.resetDrawOrders();
04631 }
04632
04633 if (high_res)
04634 {
04635 send_agent_resume();
04636 }
04637
04638 return TRUE;
04639 }
04640
04641 void LLViewerWindow::destroyWindow()
04642 {
04643 if (mWindow)
04644 {
04645 LLWindowManager::destroyWindow(mWindow);
04646 }
04647 mWindow = NULL;
04648 }
04649
04650
04651 void LLViewerWindow::drawMouselookInstructions()
04652 {
04653
04654 const char* instructions = "Press ESC to leave Mouselook.";
04655 const LLFontGL* font = LLResMgr::getInstance()->getRes( LLFONT_SANSSERIF );
04656
04657 const S32 INSTRUCTIONS_PAD = 5;
04658 LLRect instructions_rect;
04659 instructions_rect.setLeftTopAndSize(
04660 INSTRUCTIONS_PAD,
04661 getWindowHeight() - INSTRUCTIONS_PAD,
04662 font->getWidth( instructions ) + 2 * INSTRUCTIONS_PAD,
04663 llround(font->getLineHeight() + 2 * INSTRUCTIONS_PAD));
04664
04665 {
04666 LLGLSNoTexture gls_no_texture;
04667 gGL.color4f( 0.9f, 0.9f, 0.9f, 1.0f );
04668 gl_rect_2d( instructions_rect );
04669 }
04670
04671 font->renderUTF8(
04672 instructions, 0,
04673 instructions_rect.mLeft + INSTRUCTIONS_PAD,
04674 instructions_rect.mTop - INSTRUCTIONS_PAD,
04675 LLColor4( 0.0f, 0.0f, 0.0f, 1.f ),
04676 LLFontGL::LEFT, LLFontGL::TOP);
04677 }
04678
04679
04680
04681
04682
04683 void LLViewerWindow::setKeyboardFocus(LLUICtrl* new_focus)
04684 {
04685 gFocusMgr.setKeyboardFocus( new_focus );
04686 }
04687
04688 LLUICtrl* LLViewerWindow::getKeyboardFocus()
04689 {
04690 return gFocusMgr.getKeyboardFocus();
04691 }
04692
04693 BOOL LLViewerWindow::hasKeyboardFocus(const LLUICtrl* possible_focus) const
04694 {
04695 return possible_focus == gFocusMgr.getKeyboardFocus();
04696 }
04697
04698 BOOL LLViewerWindow::childHasKeyboardFocus(const LLView* parent) const
04699 {
04700 return gFocusMgr.childHasKeyboardFocus( parent );
04701 }
04702
04703 void LLViewerWindow::setMouseCapture(LLMouseHandler* new_captor)
04704 {
04705 gFocusMgr.setMouseCapture( new_captor );
04706 }
04707
04708 LLMouseHandler* LLViewerWindow::getMouseCaptor() const
04709 {
04710 return gFocusMgr.getMouseCapture();
04711 }
04712
04713 S32 LLViewerWindow::getWindowHeight() const
04714 {
04715 return mVirtualWindowRect.getHeight();
04716 }
04717
04718 S32 LLViewerWindow::getWindowWidth() const
04719 {
04720 return mVirtualWindowRect.getWidth();
04721 }
04722
04723 S32 LLViewerWindow::getWindowDisplayHeight() const
04724 {
04725 return mWindowRect.getHeight();
04726 }
04727
04728 S32 LLViewerWindow::getWindowDisplayWidth() const
04729 {
04730 return mWindowRect.getWidth();
04731 }
04732
04733 LLUICtrl* LLViewerWindow::getTopCtrl() const
04734 {
04735 return gFocusMgr.getTopCtrl();
04736 }
04737
04738 BOOL LLViewerWindow::hasTopCtrl(LLView* view) const
04739 {
04740 return view == gFocusMgr.getTopCtrl();
04741 }
04742
04743 void LLViewerWindow::setTopCtrl(LLUICtrl* new_top)
04744 {
04745 gFocusMgr.setTopCtrl( new_top );
04746 }
04747
04748 void LLViewerWindow::setupViewport(S32 x_offset, S32 y_offset)
04749 {
04750 gGLViewport[0] = x_offset;
04751 gGLViewport[1] = y_offset;
04752 gGLViewport[2] = mWindowRect.getWidth();
04753 gGLViewport[3] = mWindowRect.getHeight();
04754 glViewport(gGLViewport[0], gGLViewport[1], gGLViewport[2], gGLViewport[3]);
04755 }
04756
04757 void LLViewerWindow::setup3DRender()
04758 {
04759 LLViewerCamera::getInstance()->setPerspective(NOT_FOR_SELECTION, 0, 0, mWindowRect.getWidth(), mWindowRect.getHeight(), FALSE, LLViewerCamera::getInstance()->getNear(), MAX_FAR_CLIP*2.f);
04760 }
04761
04762 void LLViewerWindow::setup2DRender()
04763 {
04764 gl_state_for_2d(mWindowRect.getWidth(), mWindowRect.getHeight());
04765 }
04766
04767
04768 LLViewerObject *LLViewerWindow::lastObjectHit()
04769 {
04770 return gObjectList.findObject( gLastHitObjectID );
04771 }
04772
04773 const LLVector3d& LLViewerWindow::lastObjectHitOffset()
04774 {
04775 return gLastHitObjectOffset;
04776 }
04777
04778
04779 LLViewerObject *LLViewerWindow::lastNonFloraObjectHit()
04780 {
04781 return gObjectList.findObject( gLastHitNonFloraObjectID );
04782 }
04783
04784 const LLVector3d& LLViewerWindow::lastNonFloraObjectHitOffset()
04785 {
04786 return gLastHitNonFloraObjectOffset;
04787 }
04788
04789
04790 void LLViewerWindow::setShowProgress(const BOOL show)
04791 {
04792 if (mProgressView)
04793 {
04794 mProgressView->setVisible(show);
04795 }
04796 }
04797
04798 BOOL LLViewerWindow::getShowProgress() const
04799 {
04800 return (mProgressView && mProgressView->getVisible());
04801 }
04802
04803
04804 void LLViewerWindow::moveProgressViewToFront()
04805 {
04806 if( mProgressView && mRootView )
04807 {
04808 mRootView->removeChild( mProgressView );
04809 mRootView->addChild( mProgressView );
04810 }
04811 }
04812
04813 void LLViewerWindow::setProgressString(const LLString& string)
04814 {
04815 if (mProgressView)
04816 {
04817 mProgressView->setText(string);
04818 }
04819 }
04820
04821 void LLViewerWindow::setProgressMessage(const LLString& msg)
04822 {
04823 if(mProgressView)
04824 {
04825 mProgressView->setMessage(msg);
04826 }
04827 }
04828
04829 void LLViewerWindow::setProgressPercent(const F32 percent)
04830 {
04831 if (mProgressView)
04832 {
04833 mProgressView->setPercent(percent);
04834 }
04835 }
04836
04837 void LLViewerWindow::setProgressCancelButtonVisible( BOOL b, const LLString& label )
04838 {
04839 if (mProgressView)
04840 {
04841 mProgressView->setCancelButtonVisible( b, label );
04842 }
04843 }
04844
04845
04846 LLProgressView *LLViewerWindow::getProgressView() const
04847 {
04848 return mProgressView;
04849 }
04850
04851 void LLViewerWindow::dumpState()
04852 {
04853 llinfos << "LLViewerWindow Active " << S32(mActive) << llendl;
04854 llinfos << "mWindow visible " << S32(mWindow->getVisible())
04855 << " minimized " << S32(mWindow->getMinimized())
04856 << llendl;
04857 }
04858
04859 void LLViewerWindow::stopGL(BOOL save_state)
04860 {
04861 if (!gGLManager.mIsDisabled)
04862 {
04863 llinfos << "Shutting down GL..." << llendl;
04864
04865
04866 LLAppViewer::getTextureCache()->pause();
04867 LLAppViewer::getImageDecodeThread()->pause();
04868 LLAppViewer::getTextureFetch()->pause();
04869
04870 gSky.destroyGL();
04871 stop_glerror();
04872
04873 gImageList.destroyGL(save_state);
04874 stop_glerror();
04875
04876 gBumpImageList.destroyGL();
04877 stop_glerror();
04878
04879 LLFontGL::destroyGL();
04880 stop_glerror();
04881
04882 LLVOAvatar::destroyGL();
04883 stop_glerror();
04884
04885 LLDynamicTexture::destroyGL();
04886 stop_glerror();
04887
04888 if (gPipeline.isInit())
04889 {
04890 gPipeline.destroyGL();
04891 }
04892
04893 gCone.cleanupGL();
04894 gBox.cleanupGL();
04895 gSphere.cleanupGL();
04896 gCylinder.cleanupGL();
04897
04898 gGLManager.mIsDisabled = TRUE;
04899 stop_glerror();
04900
04901 llinfos << "Remaining allocated texture memory: " << LLImageGL::sGlobalTextureMemory << " bytes" << llendl;
04902 }
04903 }
04904
04905 void LLViewerWindow::restoreGL(const LLString& progress_message)
04906 {
04907 if (gGLManager.mIsDisabled)
04908 {
04909 llinfos << "Restoring GL..." << llendl;
04910 gGLManager.mIsDisabled = FALSE;
04911
04912
04913
04914 initFonts();
04915 initGLDefaults();
04916 LLGLState::restoreGL();
04917 gSky.restoreGL();
04918 gPipeline.restoreGL();
04919 LLDrawPoolWater::restoreGL();
04920 LLManipTranslate::restoreGL();
04921 gImageList.restoreGL();
04922 gBumpImageList.restoreGL();
04923 LLDynamicTexture::restoreGL();
04924 LLVOAvatar::restoreGL();
04925
04926 gResizeScreenTexture = TRUE;
04927
04928 if (gFloaterCustomize && gFloaterCustomize->getVisible())
04929 {
04930 LLVisualParamHint::requestHintUpdates();
04931 }
04932
04933 if (!progress_message.empty())
04934 {
04935 gRestoreGLTimer.reset();
04936 gRestoreGL = TRUE;
04937 setShowProgress(TRUE);
04938 setProgressString(progress_message);
04939 }
04940 llinfos << "...Restoring GL done" << llendl;
04941 #if LL_WINDOWS
04942 if(!LLWinDebug::checkExceptionHandler())
04943 {
04944 llwarns << " Someone took over my exception handler (post restoreGL)!" << llendl;
04945 }
04946 #endif
04947
04948 }
04949 }
04950
04951 void LLViewerWindow::initFonts(F32 zoom_factor)
04952 {
04953 LLFontGL::destroyGL();
04954 LLFontGL::initDefaultFonts( gSavedSettings.getF32("FontScreenDPI"),
04955 mDisplayScale.mV[VX] * zoom_factor,
04956 mDisplayScale.mV[VY] * zoom_factor,
04957 gSavedSettings.getString("FontMonospace"),
04958 gSavedSettings.getF32("FontSizeMonospace"),
04959 gSavedSettings.getString("FontSansSerif"),
04960 gSavedSettings.getString("FontSansSerifFallback"),
04961 gSavedSettings.getF32("FontSansSerifFallbackScale"),
04962 gSavedSettings.getF32("FontSizeSmall"),
04963 gSavedSettings.getF32("FontSizeMedium"),
04964 gSavedSettings.getF32("FontSizeLarge"),
04965 gSavedSettings.getF32("FontSizeHuge"),
04966 gSavedSettings.getString("FontSansSerifBold"),
04967 gSavedSettings.getF32("FontSizeMedium"),
04968 gDirUtilp->getAppRODataDir()
04969 );
04970 }
04971 void LLViewerWindow::toggleFullscreen(BOOL show_progress)
04972 {
04973 if (mWindow)
04974 {
04975 mWantFullscreen = mWindow->getFullscreen() ? FALSE : TRUE;
04976 mShowFullscreenProgress = show_progress;
04977 }
04978 }
04979
04980 void LLViewerWindow::getTargetWindow(BOOL& fullscreen, S32& width, S32& height) const
04981 {
04982 fullscreen = mWantFullscreen;
04983
04984 if (mWindow
04985 && mWindow->getFullscreen() == mWantFullscreen)
04986 {
04987 width = getWindowDisplayWidth();
04988 height = getWindowDisplayHeight();
04989 }
04990 else if (mWantFullscreen)
04991 {
04992 width = gSavedSettings.getS32("FullScreenWidth");
04993 height = gSavedSettings.getS32("FullScreenHeight");
04994 }
04995 else
04996 {
04997 width = gSavedSettings.getS32("WindowWidth");
04998 height = gSavedSettings.getS32("WindowHeight");
04999 }
05000 }
05001
05002
05003 BOOL LLViewerWindow::checkSettings()
05004 {
05005 BOOL is_fullscreen = mWindow->getFullscreen();
05006 if (is_fullscreen && !mWantFullscreen)
05007 {
05008 changeDisplaySettings(FALSE,
05009 LLCoordScreen(gSavedSettings.getS32("WindowWidth"),
05010 gSavedSettings.getS32("WindowHeight")),
05011 TRUE,
05012 mShowFullscreenProgress);
05013 return TRUE;
05014 }
05015 else if (!is_fullscreen && mWantFullscreen)
05016 {
05017 if (!LLStartUp::canGoFullscreen())
05018 {
05019 return FALSE;
05020 }
05021
05022 LLGLState::checkStates();
05023 LLGLState::checkTextureChannels();
05024 changeDisplaySettings(TRUE,
05025 LLCoordScreen(gSavedSettings.getS32("FullScreenWidth"),
05026 gSavedSettings.getS32("FullScreenHeight")),
05027 gSavedSettings.getBOOL("DisableVerticalSync"),
05028 mShowFullscreenProgress);
05029
05030 LLGLState::checkStates();
05031 LLGLState::checkTextureChannels();
05032 return TRUE;
05033 }
05034 return FALSE;
05035 }
05036
05037 void LLViewerWindow::restartDisplay(BOOL show_progress_bar)
05038 {
05039 llinfos << "Restaring GL" << llendl;
05040 stopGL();
05041 if (show_progress_bar)
05042 {
05043 restoreGL("Changing Resolution...");
05044 }
05045 else
05046 {
05047 restoreGL();
05048 }
05049 }
05050
05051 BOOL LLViewerWindow::changeDisplaySettings(BOOL fullscreen, LLCoordScreen size, BOOL disable_vsync, BOOL show_progress_bar)
05052 {
05053 BOOL was_maximized = gSavedSettings.getBOOL("WindowMaximized");
05054 mWantFullscreen = fullscreen;
05055 mShowFullscreenProgress = show_progress_bar;
05056 gSavedSettings.setBOOL("FullScreen", mWantFullscreen);
05057
05058 gResizeScreenTexture = TRUE;
05059
05060 BOOL old_fullscreen = mWindow->getFullscreen();
05061 if (!old_fullscreen && fullscreen && !LLStartUp::canGoFullscreen())
05062 {
05063
05064
05065 gSavedSettings.setS32("FullScreenWidth", size.mX);
05066 gSavedSettings.setS32("FullScreenHeight", size.mY);
05067
05068
05069 return TRUE;
05070 }
05071
05072 U32 fsaa = gSavedSettings.getU32("RenderFSAASamples");
05073 U32 old_fsaa = mWindow->getFSAASamples();
05074
05075 if (!old_fullscreen && !fullscreen)
05076 {
05077
05078 if (!mWindow->getMaximized())
05079 {
05080 mWindow->setSize(size);
05081 }
05082
05083 if (fsaa == old_fsaa)
05084 {
05085 return TRUE;
05086 }
05087 }
05088
05089
05090 LLFloaterSnapshot::hide(0);
05091
05092 BOOL result_first_try = FALSE;
05093 BOOL result_second_try = FALSE;
05094
05095 LLUICtrl* keyboard_focus = gFocusMgr.getKeyboardFocus();
05096 send_agent_pause();
05097 llinfos << "Stopping GL during changeDisplaySettings" << llendl;
05098 stopGL();
05099 mIgnoreActivate = TRUE;
05100 LLCoordScreen old_size;
05101 LLCoordScreen old_pos;
05102 mWindow->getSize(&old_size);
05103 BOOL got_position = mWindow->getPosition(&old_pos);
05104
05105 if (!old_fullscreen && fullscreen && got_position)
05106 {
05107
05108 gSavedSettings.setS32("WindowX", old_pos.mX);
05109 gSavedSettings.setS32("WindowY", old_pos.mY);
05110 }
05111
05112 mWindow->setFSAASamples(fsaa);
05113
05114 result_first_try = mWindow->switchContext(fullscreen, size, disable_vsync);
05115 if (!result_first_try)
05116 {
05117
05118 mWindow->setFSAASamples(old_fsaa);
05119 result_second_try = mWindow->switchContext(old_fullscreen, old_size, disable_vsync);
05120
05121 if (!result_second_try)
05122 {
05123
05124 send_agent_resume();
05125 mIgnoreActivate = FALSE;
05126 return FALSE;
05127 }
05128 }
05129 send_agent_resume();
05130
05131 llinfos << "Restoring GL during resolution change" << llendl;
05132 if (show_progress_bar)
05133 {
05134 restoreGL("Changing Resolution...");
05135 }
05136 else
05137 {
05138 restoreGL();
05139 }
05140
05141 if (!result_first_try)
05142 {
05143 LLStringBase<char>::format_map_t args;
05144 args["[RESX]"] = llformat("%d",size.mX);
05145 args["[RESY]"] = llformat("%d",size.mY);
05146 alertXml("ResolutionSwitchFail", args);
05147 size = old_size;
05148 }
05149
05150 BOOL success = result_first_try || result_second_try;
05151 if (success)
05152 {
05153 #if LL_WINDOWS
05154
05155
05156 if (fullscreen)
05157 #endif
05158 {
05159 reshape(size.mX, size.mY);
05160 }
05161 }
05162
05163 if (!mWindow->getFullscreen() && success)
05164 {
05165
05166 if (was_maximized)
05167 {
05168 mWindow->maximize();
05169 }
05170 else
05171 {
05172 S32 windowX = gSavedSettings.getS32("WindowX");
05173 S32 windowY = gSavedSettings.getS32("WindowY");
05174
05175 mWindow->setPosition(LLCoordScreen ( windowX, windowY ) );
05176 }
05177 }
05178
05179 mIgnoreActivate = FALSE;
05180 gFocusMgr.setKeyboardFocus(keyboard_focus);
05181 mWantFullscreen = mWindow->getFullscreen();
05182 mShowFullscreenProgress = FALSE;
05183
05184 return success;
05185 }
05186
05187
05188 F32 LLViewerWindow::getDisplayAspectRatio() const
05189 {
05190 if (mWindow->getFullscreen())
05191 {
05192 if (gSavedSettings.getBOOL("FullScreenAutoDetectAspectRatio"))
05193 {
05194 return mWindow->getNativeAspectRatio();
05195 }
05196 else
05197 {
05198 return gSavedSettings.getF32("FullScreenAspectRatio");
05199 }
05200 }
05201 else
05202 {
05203 return mWindow->getNativeAspectRatio();
05204 }
05205 }
05206
05207
05208 void LLViewerWindow::drawPickBuffer() const
05209 {
05210 if (mPickBuffer)
05211 {
05212 gGL.color4f(1,1,1,1);
05213 gGL.pushMatrix();
05214 LLGLDisable no_blend(GL_BLEND);
05215 LLGLDisable no_alpha_test(GL_ALPHA_TEST);
05216 LLGLSNoTexture no_texture;
05217 glPixelZoom(10.f, 10.f);
05218 glRasterPos2f(((F32)mPickPoint.mX * mDisplayScale.mV[VX] + 10.f),
05219 ((F32)mPickPoint.mY * mDisplayScale.mV[VY] + 10.f));
05220 glDrawPixels(PICK_DIAMETER, PICK_DIAMETER, GL_RGBA, GL_UNSIGNED_BYTE, mPickBuffer);
05221 glPixelZoom(1.f, 1.f);
05222 gGL.color4fv(LLColor4::white.mV);
05223 gl_rect_2d(llround((F32)mPickPoint.mX * mDisplayScale.mV[VX] - (F32)(PICK_HALF_WIDTH)),
05224 llround((F32)mPickPoint.mY * mDisplayScale.mV[VY] + (F32)(PICK_HALF_WIDTH)),
05225 llround((F32)mPickPoint.mX * mDisplayScale.mV[VX] + (F32)(PICK_HALF_WIDTH)),
05226 llround((F32)mPickPoint.mY * mDisplayScale.mV[VY] - (F32)(PICK_HALF_WIDTH)),
05227 FALSE);
05228 gl_line_2d(llround((F32)mPickPoint.mX * mDisplayScale.mV[VX] - (F32)(PICK_HALF_WIDTH)),
05229 llround((F32)mPickPoint.mY * mDisplayScale.mV[VY] + (F32)(PICK_HALF_WIDTH)),
05230 llround((F32)mPickPoint.mX * mDisplayScale.mV[VX] + 10.f),
05231 llround((F32)mPickPoint.mY * mDisplayScale.mV[VY] + (F32)(PICK_DIAMETER) * 10.f + 10.f));
05232 gl_line_2d(llround((F32)mPickPoint.mX * mDisplayScale.mV[VX] + (F32)(PICK_HALF_WIDTH)),
05233 llround((F32)mPickPoint.mY * mDisplayScale.mV[VY] - (F32)(PICK_HALF_WIDTH)),
05234 llround((F32)mPickPoint.mX * mDisplayScale.mV[VX] + (F32)(PICK_DIAMETER) * 10.f + 10.f),
05235 llround((F32)mPickPoint.mY * mDisplayScale.mV[VY] + 10.f));
05236 gGL.translatef(10.f, 10.f, 0.f);
05237 gl_rect_2d(llround((F32)mPickPoint.mX * mDisplayScale.mV[VX]),
05238 llround((F32)mPickPoint.mY * mDisplayScale.mV[VY] + (F32)(PICK_DIAMETER) * 10.f),
05239 llround((F32)mPickPoint.mX * mDisplayScale.mV[VX] + (F32)(PICK_DIAMETER) * 10.f),
05240 llround((F32)mPickPoint.mY * mDisplayScale.mV[VY]),
05241 FALSE);
05242 gl_rect_2d(llround((F32)mPickPoint.mX * mDisplayScale.mV[VX] + (F32)(PICK_HALF_WIDTH + mPickOffset.mX)* 10.f),
05243 llround((F32)mPickPoint.mY * mDisplayScale.mV[VY] + (F32)(PICK_HALF_WIDTH + mPickOffset.mY + 1) * 10.f),
05244 llround((F32)mPickPoint.mX * mDisplayScale.mV[VX] + (F32)(PICK_HALF_WIDTH + mPickOffset.mX + 1) * 10.f),
05245 llround((F32)mPickPoint.mY * mDisplayScale.mV[VY] + (F32)(PICK_HALF_WIDTH + mPickOffset.mY) * 10.f),
05246 FALSE);
05247 gGL.popMatrix();
05248 gGL.flush();
05249 }
05250 }
05251
05252 void LLViewerWindow::calcDisplayScale()
05253 {
05254 F32 ui_scale_factor = gSavedSettings.getF32("UIScaleFactor");
05255 LLVector2 display_scale;
05256 display_scale.setVec(llmax(1.f / mWindow->getPixelAspectRatio(), 1.f), llmax(mWindow->getPixelAspectRatio(), 1.f));
05257 F32 height_normalization = gSavedSettings.getBOOL("UIAutoScale") ? ((F32)mWindowRect.getHeight() / display_scale.mV[VY]) / 768.f : 1.f;
05258 if(mWindow->getFullscreen())
05259 {
05260 display_scale *= (ui_scale_factor * height_normalization);
05261 }
05262 else
05263 {
05264 display_scale *= ui_scale_factor;
05265 }
05266
05267
05268 if (display_scale.mV[VX] < MIN_DISPLAY_SCALE || display_scale.mV[VY] < MIN_DISPLAY_SCALE)
05269 {
05270 display_scale *= MIN_DISPLAY_SCALE / llmin(display_scale.mV[VX], display_scale.mV[VY]);
05271 }
05272
05273 if (mWindow->getFullscreen())
05274 {
05275 display_scale.mV[0] = llround(display_scale.mV[0], 2.0f/(F32) mWindowRect.getWidth());
05276 display_scale.mV[1] = llround(display_scale.mV[1], 2.0f/(F32) mWindowRect.getHeight());
05277 }
05278
05279 if (display_scale != mDisplayScale)
05280 {
05281 llinfos << "Setting display scale to " << display_scale << llendl;
05282
05283 mDisplayScale = display_scale;
05284
05285 initFonts();
05286 }
05287 }
05288
05289
05290
05291
05292 bool LLViewerWindow::alertCallback(S32 modal)
05293 {
05294 if (gNoRender)
05295 {
05296 return false;
05297 }
05298 else
05299 {
05300
05301 {
05302
05303
05304 if( gAgent.cameraMouselook() )
05305 {
05306 gAgent.changeCameraToDefault();
05307 }
05308 }
05309 return true;
05310 }
05311 }
05312
05313 LLAlertDialog* LLViewerWindow::alertXml(const std::string& xml_filename,
05314 LLAlertDialog::alert_callback_t callback, void* user_data)
05315 {
05316 LLString::format_map_t args;
05317 return alertXml( xml_filename, args, callback, user_data );
05318 }
05319
05320 LLAlertDialog* LLViewerWindow::alertXml(const std::string& xml_filename, const LLString::format_map_t& args,
05321 LLAlertDialog::alert_callback_t callback, void* user_data)
05322 {
05323 if (gNoRender)
05324 {
05325 llinfos << "Alert: " << xml_filename << llendl;
05326 if (callback)
05327 {
05328 callback(-1, user_data);
05329 }
05330 return NULL;
05331 }
05332
05333
05334
05335 if( gAgent.cameraMouselook() )
05336 {
05337 gAgent.changeCameraToDefault();
05338 }
05339
05340
05341 return LLAlertDialog::showXml( xml_filename, args, callback, user_data );
05342 }
05343
05344 LLAlertDialog* LLViewerWindow::alertXmlEditText(const std::string& xml_filename, const LLString::format_map_t& args,
05345 LLAlertDialog::alert_callback_t callback, void* user_data,
05346 LLAlertDialog::alert_text_callback_t text_callback, void *text_data,
05347 const LLString::format_map_t& edit_args, BOOL draw_asterixes)
05348 {
05349 if (gNoRender)
05350 {
05351 llinfos << "Alert: " << xml_filename << llendl;
05352 if (callback)
05353 {
05354 callback(-1, user_data);
05355 }
05356 return NULL;
05357 }
05358
05359
05360
05361 if( gAgent.cameraMouselook() )
05362 {
05363 gAgent.changeCameraToDefault();
05364 }
05365
05366
05367 LLAlertDialog* alert = LLAlertDialog::createXml( xml_filename, args, callback, user_data );
05368 if (alert)
05369 {
05370 if (text_callback)
05371 {
05372 alert->setEditTextCallback(text_callback, text_data);
05373 }
05374 alert->setEditTextArgs(edit_args);
05375 alert->setDrawAsterixes(draw_asterixes);
05376 alert->show();
05377 }
05378 return alert;
05379 }
05380
05382
05383 LLBottomPanel::LLBottomPanel(const LLRect &rect) :
05384 LLPanel("", rect, FALSE),
05385 mIndicator(NULL)
05386 {
05387
05388 setFocusRoot(TRUE);
05389
05390 setIsChrome(TRUE);
05391
05392 mFactoryMap["toolbar"] = LLCallbackMap(createToolBar, NULL);
05393 mFactoryMap["overlay"] = LLCallbackMap(createOverlayBar, NULL);
05394 mFactoryMap["hud"] = LLCallbackMap(createHUD, NULL);
05395 LLUICtrlFactory::getInstance()->buildPanel(this, "panel_bars.xml", &getFactoryMap());
05396
05397 setOrigin(rect.mLeft, rect.mBottom);
05398 reshape(rect.getWidth(), rect.getHeight());
05399 }
05400
05401 void LLBottomPanel::setFocusIndicator(LLView * indicator)
05402 {
05403 mIndicator = indicator;
05404 }
05405
05406 void LLBottomPanel::draw()
05407 {
05408 if(mIndicator)
05409 {
05410 BOOL hasFocus = gFocusMgr.childHasKeyboardFocus(this);
05411 mIndicator->setVisible(hasFocus);
05412 mIndicator->setEnabled(hasFocus);
05413 }
05414 LLPanel::draw();
05415 }
05416
05417 void* LLBottomPanel::createHUD(void* data)
05418 {
05419 delete gHUDView;
05420 gHUDView = new LLHUDView();
05421 return gHUDView;
05422 }
05423
05424
05425 void* LLBottomPanel::createOverlayBar(void* data)
05426 {
05427 delete gOverlayBar;
05428 gOverlayBar = new LLOverlayBar();
05429 return gOverlayBar;
05430 }
05431
05432 void* LLBottomPanel::createToolBar(void* data)
05433 {
05434 delete gToolBar;
05435 gToolBar = new LLToolBar();
05436 return gToolBar;
05437 }