//-------------------------------------------------------------------- // LLPolyMeshSharedData::loadMesh() //-------------------------------------------------------------------- BOOL LLPolyMeshSharedData::loadMesh( const std::string& fileName ) { //------------------------------------------------------------------------- // Open the file //------------------------------------------------------------------------- if(fileName.empty()) { LL_ERRS() << "Filename is Empty!" << LL_ENDL; return FALSE; } LLFILE* fp = LLFile::fopen(fileName, "rb"); /*Flawfinder: ignore*/ if (!fp) { LL_ERRS() << "can't open: " << fileName << LL_ENDL; return FALSE; } //------------------------------------------------------------------------- // Read a chunk //------------------------------------------------------------------------- char header[128]; /*Flawfinder: ignore*/ if (fread(header, sizeof(char), 128, fp) != 128) { LL_WARNS() << "Short read" << LL_ENDL; } //------------------------------------------------------------------------- // Check for proper binary header //------------------------------------------------------------------------- BOOL status = FALSE; if ( strncmp(header, HEADER_BINARY, strlen(HEADER_BINARY)) == 0 ) /*Flawfinder: ignore*/ { LL_DEBUGS() << "Loading " << fileName << LL_ENDL; //---------------------------------------------------------------- // File Header (seek past it) //---------------------------------------------------------------- fseek(fp, 24, SEEK_SET); //---------------------------------------------------------------- // HasWeights //---------------------------------------------------------------- U8 hasWeights; size_t numRead = fread(&hasWeights, sizeof(U8), 1, fp); if (numRead != 1) { LL_ERRS() << "can't read HasWeights flag from " << fileName << LL_ENDL; return FALSE; } if (!isLOD()) { mHasWeights = (hasWeights==0) ? FALSE : TRUE; } //---------------------------------------------------------------- // HasDetailTexCoords //---------------------------------------------------------------- U8 hasDetailTexCoords; numRead = fread(&hasDetailTexCoords, sizeof(U8), 1, fp); if (numRead != 1) { LL_ERRS() << "can't read HasDetailTexCoords flag from " << fileName << LL_ENDL; return FALSE; } //---------------------------------------------------------------- // Position //---------------------------------------------------------------- LLVector3 position; numRead = fread(position.mV, sizeof(float), 3, fp); llendianswizzle(position.mV, sizeof(float), 3); if (numRead != 3) { LL_ERRS() << "can't read Position from " << fileName << LL_ENDL; return FALSE; } setPosition( position ); //---------------------------------------------------------------- // Rotation //---------------------------------------------------------------- LLVector3 rotationAngles; numRead = fread(rotationAngles.mV, sizeof(float), 3, fp); llendianswizzle(rotationAngles.mV, sizeof(float), 3); if (numRead != 3) { LL_ERRS() << "can't read RotationAngles from " << fileName << LL_ENDL; return FALSE; } U8 rotationOrder; numRead = fread(&rotationOrder, sizeof(U8), 1, fp); if (numRead != 1) { LL_ERRS() << "can't read RotationOrder from " << fileName << LL_ENDL; return FALSE; } rotationOrder = 0; setRotation( mayaQ( rotationAngles.mV[0], rotationAngles.mV[1], rotationAngles.mV[2], (LLQuaternion::Order)rotationOrder ) ); //---------------------------------------------------------------- // Scale //---------------------------------------------------------------- LLVector3 scale; numRead = fread(scale.mV, sizeof(float), 3, fp); llendianswizzle(scale.mV, sizeof(float), 3); if (numRead != 3) { LL_ERRS() << "can't read Scale from " << fileName << LL_ENDL; return FALSE; } setScale( scale ); //------------------------------------------------------------------------- // Release any existing mesh geometry //------------------------------------------------------------------------- freeMeshData(); U16 numVertices = 0; //---------------------------------------------------------------- // NumVertices //---------------------------------------------------------------- if (!isLOD()) { numRead = fread(&numVertices, sizeof(U16), 1, fp); llendianswizzle(&numVertices, sizeof(U16), 1); if (numRead != 1) { LL_ERRS() << "can't read NumVertices from " << fileName << LL_ENDL; return FALSE; } allocateVertexData( numVertices ); for (U16 i = 0; i < numVertices; ++i) { //---------------------------------------------------------------- // Coords //---------------------------------------------------------------- numRead = fread(&mBaseCoords[i], sizeof(float), 3, fp); llendianswizzle(&mBaseCoords[i], sizeof(float), 3); if (numRead != 3) { LL_ERRS() << "can't read Coordinates from " << fileName << LL_ENDL; return FALSE; } } for (U16 i = 0; i < numVertices; ++i) { //---------------------------------------------------------------- // Normals //---------------------------------------------------------------- numRead = fread(&mBaseNormals[i], sizeof(float), 3, fp); llendianswizzle(&mBaseNormals[i], sizeof(float), 3); if (numRead != 3) { LL_ERRS() << " can't read Normals from " << fileName << LL_ENDL; return FALSE; } } for (U16 i = 0; i < numVertices; ++i) { //---------------------------------------------------------------- // Binormals //---------------------------------------------------------------- numRead = fread(&mBaseBinormals[i], sizeof(float), 3, fp); llendianswizzle(&mBaseBinormals[i], sizeof(float), 3); if (numRead != 3) { LL_ERRS() << " can't read Binormals from " << fileName << LL_ENDL; return FALSE; } } //---------------------------------------------------------------- // TexCoords //---------------------------------------------------------------- numRead = fread(mTexCoords, 2*sizeof(float), numVertices, fp); llendianswizzle(mTexCoords, sizeof(float), 2*numVertices); if (numRead != numVertices) { LL_ERRS() << "can't read TexCoords from " << fileName << LL_ENDL; return FALSE; } //---------------------------------------------------------------- // DetailTexCoords //---------------------------------------------------------------- if (mHasDetailTexCoords) { numRead = fread(mDetailTexCoords, 2*sizeof(float), numVertices, fp); llendianswizzle(mDetailTexCoords, sizeof(float), 2*numVertices); if (numRead != numVertices) { LL_ERRS() << "can't read DetailTexCoords from " << fileName << LL_ENDL; return FALSE; } } //---------------------------------------------------------------- // Weights //---------------------------------------------------------------- if (mHasWeights) { numRead = fread(mWeights, sizeof(float), numVertices, fp); llendianswizzle(mWeights, sizeof(float), numVertices); if (numRead != numVertices) { LL_ERRS() << "can't read Weights from " << fileName << LL_ENDL; return FALSE; } } } //---------------------------------------------------------------- // NumFaces //---------------------------------------------------------------- U16 numFaces; numRead = fread(&numFaces, sizeof(U16), 1, fp); llendianswizzle(&numFaces, sizeof(U16), 1); if (numRead != 1) { LL_ERRS() << "can't read NumFaces from " << fileName << LL_ENDL; return FALSE; } allocateFaceData( numFaces ); //---------------------------------------------------------------- // Faces //---------------------------------------------------------------- U32 i; U32 numTris = 0; for (i = 0; i < numFaces; i++) { S16 face[3]; numRead = fread(face, sizeof(U16), 3, fp); llendianswizzle(face, sizeof(U16), 3); if (numRead != 3) { LL_ERRS() << "can't read Face[" << i << "] from " << fileName << LL_ENDL; return FALSE; } if (mReferenceData) { llassert(face[0] < mReferenceData->mNumVertices); llassert(face[1] < mReferenceData->mNumVertices); llassert(face[2] < mReferenceData->mNumVertices); } if (isLOD()) { // store largest index in case of LODs for (S32 j = 0; j < 3; j++) { if (face[j] > mNumVertices - 1) { mNumVertices = face[j] + 1; } } } mFaces[i][0] = face[0]; mFaces[i][1] = face[1]; mFaces[i][2] = face[2]; // S32 j; // for(j = 0; j < 3; j++) // { // std::vector<S32> *face_list = mVertFaceMap.getIfThere(face[j]); // if (!face_list) // { // face_list = new std::vector<S32>; // mVertFaceMap.addData(face[j], face_list); // } // face_list->put(i); // } numTris++; } LL_DEBUGS() << "verts: " << numVertices << ", faces: " << numFaces << ", tris: " << numTris << LL_ENDL; //---------------------------------------------------------------- // NumSkinJoints //---------------------------------------------------------------- if (!isLOD()) { U16 numSkinJoints = 0; if ( mHasWeights ) { numRead = fread(&numSkinJoints, sizeof(U16), 1, fp); llendianswizzle(&numSkinJoints, sizeof(U16), 1); if (numRead != 1) { LL_ERRS() << "can't read NumSkinJoints from " << fileName << LL_ENDL; return FALSE; } allocateJointNames( numSkinJoints ); } //---------------------------------------------------------------- // SkinJoints //---------------------------------------------------------------- for (i=0; i < numSkinJoints; i++) { char jointName[64+1]; numRead = fread(jointName, sizeof(jointName)-1, 1, fp); jointName[sizeof(jointName)-1] = '\0'; // ensure nul-termination if (numRead != 1) { LL_ERRS() << "can't read Skin[" << i << "].Name from " << fileName << LL_ENDL; return FALSE; } std::string *jn = &mJointNames[i]; *jn = jointName; } //------------------------------------------------------------------------- // look for morph section //------------------------------------------------------------------------- char morphName[64+1]; morphName[sizeof(morphName)-1] = '\0'; // ensure nul-termination while(fread(morphName, sizeof(char), 64, fp) == 64) { if (!strcmp(morphName, "End Morphs")) { // we reached the end of the morphs break; } LLPolyMorphData* morph_data = new LLPolyMorphData(std::string(morphName)); BOOL result = morph_data->loadBinary(fp, this); if (!result) { delete morph_data; continue; } mMorphData.insert(morph_data); if (!strcmp(morphName, "Breast_Female_Cleavage")) { mMorphData.insert(clone_morph_param_cleavage(morph_data, .75f, "Breast_Physics_LeftRight_Driven")); } if (!strcmp(morphName, "Breast_Female_Cleavage")) { mMorphData.insert(clone_morph_param_duplicate(morph_data, "Breast_Physics_InOut_Driven")); } if (!strcmp(morphName, "Breast_Gravity")) { mMorphData.insert(clone_morph_param_duplicate(morph_data, "Breast_Physics_UpDown_Driven")); } if (!strcmp(morphName, "Big_Belly_Torso")) { mMorphData.insert(clone_morph_param_direction(morph_data, LLVector3(0,0,0.05f), "Belly_Physics_Torso_UpDown_Driven")); } if (!strcmp(morphName, "Big_Belly_Legs")) { mMorphData.insert(clone_morph_param_direction(morph_data, LLVector3(0,0,0.05f), "Belly_Physics_Legs_UpDown_Driven")); } if (!strcmp(morphName, "skirt_belly")) { mMorphData.insert(clone_morph_param_direction(morph_data, LLVector3(0,0,0.05f), "Belly_Physics_Skirt_UpDown_Driven")); } if (!strcmp(morphName, "Small_Butt")) { mMorphData.insert(clone_morph_param_direction(morph_data, LLVector3(0,0,0.05f), "Butt_Physics_UpDown_Driven")); } if (!strcmp(morphName, "Small_Butt")) { mMorphData.insert(clone_morph_param_direction(morph_data, LLVector3(0,0.03f,0), "Butt_Physics_LeftRight_Driven")); } } S32 numRemaps; if (fread(&numRemaps, sizeof(S32), 1, fp) == 1) { llendianswizzle(&numRemaps, sizeof(S32), 1); for (S32 i = 0; i < numRemaps; i++) { S32 remapSrc; S32 remapDst; if (fread(&remapSrc, sizeof(S32), 1, fp) != 1) { LL_ERRS() << "can't read source vertex in vertex remap data" << LL_ENDL; break; } if (fread(&remapDst, sizeof(S32), 1, fp) != 1) { LL_ERRS() << "can't read destination vertex in vertex remap data" << LL_ENDL; break; } llendianswizzle(&remapSrc, sizeof(S32), 1); llendianswizzle(&remapDst, sizeof(S32), 1); mSharedVerts[remapSrc] = remapDst; } } } status = TRUE; } else { LL_ERRS() << "invalid mesh file header: " << fileName << LL_ENDL; status = FALSE; } if (0 == mNumJointNames) { allocateJointNames(1); } fclose( fp ); return status; }
LLSD LLObjectBackup::primsToLLSD(LLViewerObject::child_list_t child_list, bool is_attachment) { LLViewerObject* object; LLSD llsd; char localid[16]; LLUUID t_id; for (LLViewerObject::child_list_t::iterator i = child_list.begin(); i != child_list.end(); ++i) { object = (*i); LLUUID id = object->getID(); LL_INFOS() << "Exporting prim " << object->getID().asString() << LL_ENDL; // Create an LLSD object that represents this prim. It will be injected // in to the overall LLSD tree structure LLSD prim_llsd; if (!object->isRoot()) { // Parent id snprintf(localid, sizeof(localid), "%u", object->getSubParent()->getLocalID()); prim_llsd["parent"] = localid; } // Name and description LLSelectNode* node = LLSelectMgr::getInstance()->getSelection()->findNode(object); if (node) { prim_llsd["name"] = node->mName; prim_llsd["description"] = node->mDescription; } // Transforms if (is_attachment) { prim_llsd["position"] = object->getPositionEdit().getValue(); prim_llsd["rotation"] = ll_sd_from_quaternion(object->getRotationEdit()); } else { prim_llsd["position"] = object->getPosition().getValue(); prim_llsd["rotation"] = ll_sd_from_quaternion(object->getRotation()); } prim_llsd["scale"] = object->getScale().getValue(); // Flags prim_llsd["phantom"] = object->flagPhantom(); // legacy prim_llsd["physical"] = object->flagUsePhysics(); // legacy prim_llsd["flags"] = (S32)object->getFlags(); // new way // Extra physics flags if (mGotExtraPhysics) { LLSD& physics = prim_llsd["ExtraPhysics"]; physics["PhysicsShapeType"] = object->getPhysicsShapeType(); physics["Gravity"] = object->getPhysicsGravity(); physics["Friction"] = object->getPhysicsFriction(); physics["Density"] = object->getPhysicsDensity(); physics["Restitution"] = object->getPhysicsRestitution(); } // Click action if (S32 action = object->getClickAction()) // Non-zero prim_llsd["clickaction"] = action; // Prim material prim_llsd["material"] = object->getMaterial(); // Volume params LLVolumeParams params = object->getVolume()->getParams(); prim_llsd["volume"] = params.asLLSD(); // Extra paramsb6fab961-af18-77f8-cf08-f021377a7244 if (object->isFlexible()) { // Flexible LLFlexibleObjectData* flex; flex = (LLFlexibleObjectData*)object->getParameterEntry(LLNetworkData::PARAMS_FLEXIBLE); prim_llsd["flexible"] = flex->asLLSD(); } if (object->getParameterEntryInUse(LLNetworkData::PARAMS_LIGHT)) { // Light LLLightParams* light; light = (LLLightParams*)object->getParameterEntry(LLNetworkData::PARAMS_LIGHT); prim_llsd["light"] = light->asLLSD(); } if (object->getParameterEntryInUse(LLNetworkData::PARAMS_LIGHT_IMAGE)) { // Light image LLLightImageParams* light_param; light_param = (LLLightImageParams*)object->getParameterEntry(LLNetworkData::PARAMS_LIGHT_IMAGE); t_id = validateTextureID(light_param->getLightTexture()); if (mTexturesList.count(t_id) == 0) { LL_INFOS() << "Found a light texture, adding to list " << t_id << LL_ENDL; mTexturesList.insert(t_id); } prim_llsd["light_texture"] = light_param->asLLSD(); } if (object->getParameterEntryInUse(LLNetworkData::PARAMS_SCULPT)) { // Sculpt LLSculptParams* sculpt; sculpt = (LLSculptParams*)object->getParameterEntry(LLNetworkData::PARAMS_SCULPT); prim_llsd["sculpt"] = sculpt->asLLSD(); if ((sculpt->getSculptType() & LL_SCULPT_TYPE_MASK) != LL_SCULPT_TYPE_MESH) { LLUUID sculpt_texture = sculpt->getSculptTexture(); if (sculpt_texture == validateTextureID(sculpt_texture)) { if (mTexturesList.count(sculpt_texture) == 0) { LL_INFOS() << "Found a sculpt texture, adding to list " << sculpt_texture << LL_ENDL; mTexturesList.insert(sculpt_texture); } } else { LL_WARNS() << "Incorrect permission to export a sculpt texture." << LL_ENDL; mExportState = EXPORT_FAILED; } } } // Textures and materials LLSD te_llsd; LLSD this_te_llsd; LLSD te_mat_llsd; LLSD this_te_mat_llsd; bool has_materials = false; for (U8 i = 0, count = object->getNumTEs(); i < count; ++i) { LLTextureEntry* te = object->getTE(i); if (!te) continue; // Paranoia // Normal texture/diffuse map t_id = validateTextureID(te->getID()); this_te_llsd = te->asLLSD(); this_te_llsd["imageid"] = t_id; te_llsd.append(this_te_llsd); // Do not export non-existent default textures if (t_id != LL_TEXTURE_BLANK && t_id != LL_TEXTURE_INVISIBLE) { if (mTexturesList.count(t_id) == 0) { mTexturesList.insert(t_id); } } // Materials LLMaterial* mat = te->getMaterialParams().get(); if (mat) { has_materials = true; this_te_mat_llsd = mat->asLLSD(); t_id = validateTextureID(mat->getNormalID()); this_te_mat_llsd["NormMap"] = t_id; if (mTexturesList.count(t_id) == 0) { mTexturesList.insert(t_id); } t_id = validateTextureID(mat->getSpecularID()); this_te_mat_llsd["SpecMap"] = t_id; if (mTexturesList.count(t_id) == 0) { mTexturesList.insert(t_id); } te_mat_llsd.append(this_te_mat_llsd); } } prim_llsd["textures"] = te_llsd; if (has_materials) { prim_llsd["materials"] = te_mat_llsd; } // The keys in the primitive maps do not have to be localids, they can // be any string. We simply use localids because they are a unique // identifier snprintf(localid, sizeof(localid), "%u", object->getLocalID()); llsd[(const char*)localid] = prim_llsd; } updateExportNumbers(); return llsd; }
void LLObjectBackup::exportNextTexture() { LLUUID id; textures_set_t::iterator iter = mTexturesList.begin(); while (true) { if (mTexturesList.empty()) { mCheckNextTexture = true; LL_INFOS() << "Finished exporting textures." << LL_ENDL; return; } if (iter == mTexturesList.end()) { // Not yet ready, wait and re-check at next idle callback... mCheckNextTexture = true; return; } id = *iter++; if (id.isNull()) { // NULL texture id: just remove and ignore. mTexturesList.erase(id); LL_DEBUGS("ObjectBackup") << "Null texture UUID found, ignoring." << LL_ENDL; continue; } LLViewerTexture* imagep = LLViewerTextureManager::findTexture(id); if (imagep) { if (imagep->getDiscardLevel() > 0) { // Boost texture loading imagep->setBoostLevel(LLGLTexture::BOOST_PREVIEW); LL_DEBUGS("ObjectBackup") << "Boosting texture: " << id << LL_ENDL; LLViewerFetchedTexture* tex; tex = LLViewerTextureManager::staticCastToFetchedTexture(imagep); if (tex && tex->getDesiredDiscardLevel() > 0) { // Set min discard level to 0 tex->setMinDiscardLevel(0); LL_DEBUGS("ObjectBackup") << "Min discard level set to 0 for texture: " << id << LL_ENDL; } } else { // Texture is ready ! break; } } else { LL_WARNS() << "We *DON'T* have the texture " << id << LL_ENDL; mNonExportedTextures |= TEXTURE_MISSING; mTexturesList.erase(id); } } mTexturesList.erase(id); LL_INFOS() << "Requesting texture " << id << " from cache." << LL_ENDL; LLImageJ2C* mFormattedImage = new LLImageJ2C; BackupCacheReadResponder* responder; responder = new BackupCacheReadResponder(id, mFormattedImage); LLAppViewer::getTextureCache()->readFromCache(id, LLWorkerThread::PRIORITY_HIGH, 0, 999999, responder); }
void FSFloaterVoiceControls::updateSession() { LLVoiceChannel* voice_channel = LLVoiceChannel::getCurrentVoiceChannel(); if (voice_channel) { LL_DEBUGS("Voice") << "Current voice channel: " << voice_channel->getSessionID() << LL_ENDL; if (mSpeakerManager && voice_channel->getSessionID() == mSpeakerManager->getSessionID()) { LL_DEBUGS("Voice") << "Speaker manager is already set for session: " << voice_channel->getSessionID() << LL_ENDL; return; } else { mSpeakerManager = NULL; } } const LLUUID& session_id = voice_channel ? voice_channel->getSessionID() : LLUUID::null; LLIMModel::LLIMSession* im_session = LLIMModel::getInstance()->findIMSession(session_id); if (im_session) { mSpeakerManager = LLIMModel::getInstance()->getSpeakerManager(session_id); switch (im_session->mType) { case IM_NOTHING_SPECIAL: case IM_SESSION_P2P_INVITE: mVoiceType = VC_PEER_TO_PEER; if (!im_session->mOtherParticipantIsAvatar) { mVoiceType = VC_PEER_TO_PEER_AVALINE; } break; case IM_SESSION_CONFERENCE_START: case IM_SESSION_GROUP_START: case IM_SESSION_INVITE: if (gAgent.isInGroup(session_id)) { mVoiceType = VC_GROUP_CHAT; } else { mVoiceType = VC_AD_HOC_CHAT; } break; default: LL_WARNS() << "Failed to determine voice call IM type" << LL_ENDL; mVoiceType = VC_GROUP_CHAT; break; } } if (NULL == mSpeakerManager) { // By default show nearby chat participants mSpeakerManager = LLLocalSpeakerMgr::getInstance(); LL_DEBUGS("Voice") << "Set DEFAULT speaker manager" << LL_ENDL; mVoiceType = VC_LOCAL_CHAT; } updateTitle(); // Hide "Leave Call" button for nearby chat bool is_local_chat = mVoiceType == VC_LOCAL_CHAT; getChildView("leave_call_btn_panel")->setVisible( !is_local_chat); refreshParticipantList(); updateAgentModeratorState(); // Show floater for voice calls & only in CONNECTED to voice channel state if (!is_local_chat && voice_channel && LLVoiceChannel::STATE_CONNECTED == voice_channel->getState()) { // <FS:Ansariel> [FS communication UI] //LLIMFloater* im_floater = LLIMFloater::findInstance(session_id); FSFloaterIM* im_floater = FSFloaterIM::findInstance(session_id); // </FS:Ansariel> [FS communication UI] bool show_me = !(im_floater && im_floater->getVisible()); if (show_me) { setVisible(true); } } // [RLVa:KB] - Checked: 2010-06-05 (RLVa-1.2.0d) | Added: RLVa-1.2.0d mAvatarList->setRlvCheckShowNames(is_local_chat); // [/RLVa:KB] }
// This is fired when the update packet is processed so we know the prim // settings have stuck //static void LLObjectBackup::primUpdate(LLViewerObject* object) { LLObjectBackup* self = findInstance(); if (!object || !self || !self->mRunning || object->mID != self->mExpectingUpdate) { return; } ++self->mCurPrim; self->updateImportNumbers(); ++self->mPrimImportIter; self->mExpectingUpdate.setNull(); if (self->mPrimImportIter == self->mThisGroup.endMap()) { LL_INFOS() << "Trying to link..." << LL_ENDL; if (self->mToSelect.size() > 1) { std::reverse(self->mToSelect.begin(), self->mToSelect.end()); // Now link LLSelectMgr::getInstance()->deselectAll(); LLSelectMgr::getInstance()->selectObjectAndFamily(self->mToSelect, true); LLSelectMgr::getInstance()->sendLink(); LLViewerObject* root = self->mToSelect.back(); root->setRotation(self->mRootRot); } ++self->mCurObject; ++self->mGroupPrimImportIter; if (self->mGroupPrimImportIter != self->mLLSD["data"].endArray()) { self->importNextObject(); return; } self->mRunning = false; self->destroy(); return; } LLSD prim_llsd = self->mThisGroup[self->mPrimImportIter->first]; if (self->mToSelect.empty()) { LL_WARNS() << "error: ran out of objects to mod." << LL_ENDL; self->mRunning = false; self->destroy(); return; } if (self->mPrimImportIter != self->mThisGroup.endMap()) { //rezAgentOffset(LLVector3(1.0, 0.0, 0.0)); LLSD prim_llsd =self-> mThisGroup[self->mPrimImportIter->first]; ++self->mProcessIter; self->xmlToPrim(prim_llsd, *(self->mProcessIter)); } }
void LLPluginProcessParent::idle(void) { bool idle_again; do { // process queued messages mIncomingQueueMutex.lock(); while(!mIncomingQueue.empty()) { LLPluginMessage message = mIncomingQueue.front(); mIncomingQueue.pop(); mIncomingQueueMutex.unlock(); receiveMessage(message); mIncomingQueueMutex.lock(); } mIncomingQueueMutex.unlock(); // Give time to network processing if(mMessagePipe) { // Drain any queued outgoing messages mMessagePipe->pumpOutput(); // Only do input processing here if this instance isn't in a pollset. if(!mPolledInput) { mMessagePipe->pumpInput(); } } if(mState <= STATE_RUNNING) { if(APR_STATUS_IS_EOF(mSocketError)) { // Plugin socket was closed. This covers both normal plugin termination and plugin crashes. errorState(); } else if(mSocketError != APR_SUCCESS) { // The socket is in an error state -- the plugin is gone. LL_WARNS("Plugin") << "Socket hit an error state (" << mSocketError << ")" << LL_ENDL; errorState(); } } // If a state needs to go directly to another state (as a performance enhancement), it can set idle_again to true after calling setState(). // USE THIS CAREFULLY, since it can starve other code. Specifically make sure there's no way to get into a closed cycle and never return. // When in doubt, don't do it. idle_again = false; switch(mState) { case STATE_UNINITIALIZED: break; case STATE_INITIALIZED: { apr_status_t status = APR_SUCCESS; apr_sockaddr_t* addr = NULL; mListenSocket = LLSocket::create(gAPRPoolp, LLSocket::STREAM_TCP); mBoundPort = 0; // This code is based on parts of LLSocket::create() in lliosocket.cpp. status = apr_sockaddr_info_get( &addr, "127.0.0.1", APR_INET, mPortToBind, // port 0 = ephemeral ("find me a port") 0, gAPRPoolp); if(ll_apr_warn_status(status)) { killSockets(); errorState(); break; } // This allows us to reuse the address on quick down/up. This is unlikely to create problems. ll_apr_warn_status(apr_socket_opt_set(mListenSocket->getSocket(), APR_SO_REUSEADDR, 1)); status = apr_socket_bind(mListenSocket->getSocket(), addr); if(ll_apr_warn_status(status)) { killSockets(); errorState(); break; } // Get the actual port the socket was bound to { apr_sockaddr_t* bound_addr = NULL; if(ll_apr_warn_status(apr_socket_addr_get(&bound_addr, APR_LOCAL, mListenSocket->getSocket()))) { killSockets(); errorState(); break; } mBoundPort = bound_addr->port; if(mBoundPort == 0) { LL_WARNS("Plugin") << "Bound port number unknown, bailing out." << LL_ENDL; killSockets(); // <ND> FIRE-3877; Some drivers, eg bigfoot. Refuse to tell us which port is used when the socket is bound on port 0 (= choose a free port). // If not out of retry attempts, choose a random port between 5500 - 60000 and try again. if( mBindRetries > 10 ) //In theory we could have bad luck and randomly draft already used ports each try. In practice we already deal with a buggy driver anyway. So just fail instead hogging resources in a loop. errorState(); else { ++mBindRetries; mPortToBind = ll_rand(55000)+5000; // Ports < 4096 are reserved for root (at least on BSD like systems), do never touch them. setState( STATE_INITIALIZED ); idle_again = true; // Just try a new loop to bind the socket } // </ND> break; } } LL_DEBUGS("Plugin") << "Bound tcp socket to port: " << addr->port << LL_ENDL; // Make the listen socket non-blocking status = apr_socket_opt_set(mListenSocket->getSocket(), APR_SO_NONBLOCK, 1); if(ll_apr_warn_status(status)) { killSockets(); errorState(); break; } apr_socket_timeout_set(mListenSocket->getSocket(), 0); if(ll_apr_warn_status(status)) { killSockets(); errorState(); break; } // If it's a stream based socket, we need to tell the OS // to keep a queue of incoming connections for ACCEPT. status = apr_socket_listen( mListenSocket->getSocket(), 10); // FIXME: Magic number for queue size if(ll_apr_warn_status(status)) { killSockets(); errorState(); break; } // If we got here, we're listening. setState(STATE_LISTENING); } break; case STATE_LISTENING: { // Launch the plugin process. // Only argument to the launcher is the port number we're listening on mProcessParams.args.add(stringize(mBoundPort)); if (! (mProcess = LLProcess::create(mProcessParams))) { errorState(); } else { if(mDebug) { #if LL_DARWIN // If we're set to debug, start up a gdb instance in a new terminal window and have it attach to the plugin process and continue. // The command we're constructing would look like this on the command line: // osascript -e 'tell application "Terminal"' -e 'set win to do script "gdb -pid 12345"' -e 'do script "continue" in win' -e 'end tell' LLProcess::Params params; params.executable = "/usr/bin/osascript"; params.args.add("-e"); params.args.add("tell application \"Terminal\""); params.args.add("-e"); params.args.add(STRINGIZE("set win to do script \"gdb -pid " << mProcess->getProcessID() << "\"")); params.args.add("-e"); params.args.add("do script \"continue\" in win"); params.args.add("-e"); params.args.add("end tell"); mDebugger = LLProcess::create(params); #endif } // This will allow us to time out if the process never starts. mHeartbeat.start(); mHeartbeat.setTimerExpirySec(mPluginLaunchTimeout); setState(STATE_LAUNCHED); } } break; case STATE_LAUNCHED: // waiting for the plugin to connect if(pluginLockedUpOrQuit()) { errorState(); } else { // Check for the incoming connection. if(accept()) { // Stop listening on the server port mListenSocket.reset(); setState(STATE_CONNECTED); } } break; case STATE_CONNECTED: // waiting for hello message from the plugin if(pluginLockedUpOrQuit()) { errorState(); } break; case STATE_HELLO: LL_DEBUGS("Plugin") << "received hello message" << LL_ENDL; // Send the message to load the plugin { LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_INTERNAL, "load_plugin"); message.setValue("file", mPluginFile); message.setValue("dir", mPluginDir); sendMessage(message); } setState(STATE_LOADING); break; case STATE_LOADING: // The load_plugin_response message will kick us from here into STATE_RUNNING if(pluginLockedUpOrQuit()) { errorState(); } break; case STATE_RUNNING: if(pluginLockedUpOrQuit()) { errorState(); } break; case STATE_EXITING: if (! LLProcess::isRunning(mProcess)) { setState(STATE_CLEANUP); } else if(pluginLockedUp()) { LL_WARNS("Plugin") << "timeout in exiting state, bailing out" << LL_ENDL; errorState(); } break; case STATE_LAUNCH_FAILURE: if(mOwner != NULL) { mOwner->pluginLaunchFailed(); } setState(STATE_CLEANUP); break; case STATE_ERROR: if(mOwner != NULL) { mOwner->pluginDied(); } setState(STATE_CLEANUP); break; case STATE_CLEANUP: LLProcess::kill(mProcess); killSockets(); setState(STATE_DONE); break; case STATE_DONE: // just sit here. break; } } while (idle_again); }
void LLPluginProcessParent::poll(F64 timeout) { if(sPollsetNeedsRebuild || !sUseReadThread) { sPollsetNeedsRebuild = false; updatePollset(); } if(sPollSet) { apr_status_t status; apr_int32_t count; const apr_pollfd_t *descriptors; status = apr_pollset_poll(sPollSet, (apr_interval_time_t)(timeout * 1000000), &count, &descriptors); if(status == APR_SUCCESS) { // One or more of the descriptors signalled. Call them. for(int i = 0; i < count; i++) { LLPluginProcessParent *self = (LLPluginProcessParent *)(descriptors[i].client_data); // NOTE: the descriptor returned here is actually a COPY of the original (even though we create the pollset with APR_POLLSET_NOCOPY). // This means that even if the parent has set its mPollFD.client_data to NULL, the old pointer may still there in this descriptor. // It's even possible that the old pointer no longer points to a valid LLPluginProcessParent. // This means that we can't safely dereference the 'self' pointer here without some extra steps... if(self) { // Make sure this pointer is still in the instances list bool valid = false; { LLMutexLock lock(sInstancesMutex); for(std::list<LLPluginProcessParent*>::iterator iter = sInstances.begin(); iter != sInstances.end(); ++iter) { if(*iter == self) { // Lock the instance's mutex before unlocking the global mutex. // This avoids a possible race condition where the instance gets deleted between this check and the servicePoll() call. self->mIncomingQueueMutex.lock(); valid = true; break; } } } if(valid) { // The instance is still valid. // Pull incoming messages off the socket self->servicePoll(); self->mIncomingQueueMutex.unlock(); } else { LL_DEBUGS("PluginPoll") << "detected deleted instance " << self << LL_ENDL; } } } } else if(APR_STATUS_IS_TIMEUP(status)) { // timed out with no incoming data. Just return. } else if(status == EBADF) { // This happens when one of the file descriptors in the pollset is destroyed, which happens whenever a plugin's socket is closed. // The pollset has been or will be recreated, so just return. LL_DEBUGS("PluginPoll") << "apr_pollset_poll returned EBADF" << LL_ENDL; } else if(status != APR_SUCCESS) { LL_WARNS("PluginPoll") << "apr_pollset_poll failed with status " << status << LL_ENDL; } } }
/* virtual */ void LLPluginProcessChild::receivePluginMessage(const std::string &message) { LL_DEBUGS("PluginChild") << "Received from plugin: " << message << LL_ENDL; if(mBlockingRequest) { // LL_ERRS("Plugin") << "Can't send a message while already waiting on a blocking request -- aborting!" << LL_ENDL; } // Incoming message from the plugin instance bool passMessage = true; // FIXME: how should we handle queueing here? // Intercept certain base messages (responses to ones sent by this class) { // Decode this message LLPluginMessage parsed; parsed.parse(message); if(parsed.hasValue("blocking_request")) { mBlockingRequest = true; } std::string message_class = parsed.getClass(); if(message_class == "base") { std::string message_name = parsed.getName(); if(message_name == "init_response") { // The plugin has finished initializing. setState(STATE_RUNNING); // Don't pass this message up to the parent passMessage = false; LLPluginMessage new_message(LLPLUGIN_MESSAGE_CLASS_INTERNAL, "load_plugin_response"); LLSD versions = parsed.getValueLLSD("versions"); new_message.setValueLLSD("versions", versions); if(parsed.hasValue("plugin_version")) { std::string plugin_version = parsed.getValue("plugin_version"); new_message.setValueLLSD("plugin_version", plugin_version); } // Let the parent know it's loaded and initialized. sendMessageToParent(new_message); } else if(message_name == "shm_remove_response") { // Don't pass this message up to the parent passMessage = false; std::string name = parsed.getValue("name"); sharedMemoryRegionsType::iterator iter = mSharedMemoryRegions.find(name); if(iter != mSharedMemoryRegions.end()) { // detach the shared memory region iter->second->detach(); // and remove it from our map mSharedMemoryRegions.erase(iter); // Finally, send the response to the parent. LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_INTERNAL, "shm_remove_response"); message.setValue("name", name); sendMessageToParent(message); } else { LL_WARNS("PluginChild") << "shm_remove_response for unknown memory segment!" << LL_ENDL; } } else if (message_name == "cleanup_reply") { LL_DEBUGS("PluginChild") << "cleanup_reply message received" << LL_ENDL; passMessage = false; setState(STATE_UNLOADING_CLEANED); // Clean up this and tell the parent LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_INTERNAL, "cleanup_reply"); sendMessageToParent(message); } } } if(passMessage) { LL_DEBUGS("PluginChild") << "Passing through to parent: " << message << LL_ENDL; writeMessageRaw(message); } while(mBlockingRequest) { // The plugin wants to block and wait for a response to this message. sleep(mSleepTime); // this will pump the message pipe and process messages if(mBlockingResponseReceived || mSocketError != APR_SUCCESS || (mMessagePipe == NULL)) { // Response has been received, or we've hit an error state. Stop waiting. mBlockingRequest = false; mBlockingResponseReceived = false; } } }
LLSD LLUserAuth::parseValues(UserAuthcode &auth_code, const std::string& key_pfx, XMLRPC_VALUE param) { auth_code = E_OK; LLSD responses; for(XMLRPC_VALUE current = XMLRPC_VectorRewind(param); current; current = XMLRPC_VectorNext(param)) { std::string key(XMLRPC_GetValueID(current)); LL_DEBUGS() << "key: " << key_pfx << key << LL_ENDL; XMLRPC_VALUE_TYPE_EASY type = XMLRPC_GetValueTypeEasy(current); if(xmlrpc_type_string == type) { LLSD::String val(XMLRPC_GetValueString(current)); LL_DEBUGS() << "val: " << val << LL_ENDL; responses.insert(key,val); } else if(xmlrpc_type_int == type) { LLSD::Integer val(XMLRPC_GetValueInt(current)); LL_DEBUGS() << "val: " << val << LL_ENDL; responses.insert(key,val); } else if (xmlrpc_type_double == type) { LLSD::Real val(XMLRPC_GetValueDouble(current)); LL_DEBUGS() << "val: " << val << LL_ENDL; responses.insert(key,val); } else if(xmlrpc_type_array == type) { // We expect this to be an array of submaps. Walk the array, // recursively parsing each submap and collecting them. LLSD array; int i = 0; // for descriptive purposes for (XMLRPC_VALUE row = XMLRPC_VectorRewind(current); row; row = XMLRPC_VectorNext(current), ++i) { // Recursive call. For the lower-level key_pfx, if 'key' // is "foo", pass "foo[0]:", then "foo[1]:", etc. In the // nested call, a subkey "bar" will then be logged as // "foo[0]:bar", and so forth. // Parse the scalar subkey/value pairs from this array // entry into a temp submap. Collect such submaps in 'array'. std::string key_prefix = key_pfx; array.append(parseValues(auth_code, STRINGIZE(key_pfx << key << '[' << i << "]:"), row)); } // Having collected an 'array' of 'submap's, insert that whole // 'array' as the value of this 'key'. responses.insert(key, array); } else if (xmlrpc_type_struct == type) { LLSD submap = parseValues(auth_code, STRINGIZE(key_pfx << key << ':'), current); responses.insert(key, submap); } else { // whoops - unrecognized type LL_WARNS() << "Unhandled xmlrpc type " << type << " for key " << key_pfx << key << LL_ENDL; responses.insert(key, STRINGIZE("<bad XMLRPC type " << type << '>')); auth_code = E_UNHANDLED_ERROR; } } return responses; }
//----------------------------------------------------------------------------- // setPointAt() // called by agent logic to set look at behavior locally, and propagate to sim //----------------------------------------------------------------------------- BOOL LLHUDEffectPointAt::setPointAt(EPointAtType target_type, LLViewerObject *object, LLVector3 position) { if (!mSourceObject) { return FALSE; } if (target_type >= POINTAT_NUM_TARGETS) { LL_WARNS() << "Bad target_type " << (int)target_type << " - ignoring." << LL_ENDL; return FALSE; } // must be same or higher priority than existing effect if (POINTAT_PRIORITIES[target_type] < POINTAT_PRIORITIES[mTargetType]) { return FALSE; } F32 current_time = mTimer.getElapsedTimeF32(); // type of pointat behavior or target object has changed BOOL targetTypeChanged = (target_type != mTargetType) || (object != mTargetObject); BOOL targetPosChanged = (dist_vec_squared(position, mLastSentOffsetGlobal) > MIN_DELTAPOS_FOR_UPDATE_SQUARED) && ((current_time - mLastSendTime) > (1.f / MAX_SENDS_PER_SEC)); if (targetTypeChanged || targetPosChanged) { mLastSentOffsetGlobal = position; setDuration(POINTAT_TIMEOUTS[target_type]); setNeedsSendToSim(TRUE); // LL_INFOS() << "Sending pointat data" << LL_ENDL; } if (target_type == POINTAT_TARGET_CLEAR) { clearPointAtTarget(); } else { mTargetType = target_type; mTargetObject = object; if (object) { mTargetOffsetGlobal.setVec(position); } else { mTargetOffsetGlobal = gAgent.getPosGlobalFromAgent(position); } mKillTime = mTimer.getElapsedTimeF32() + mDuration; //set up requisite animation data update(); } return TRUE; }
void LLPluginProcessChild::receiveMessageRaw(const std::string &message) { // Incoming message from the TCP Socket LL_DEBUGS("PluginChild") << "Received from parent: " << message << LL_ENDL; // Decode this message LLPluginMessage parsed; parsed.parse(message); if(mBlockingRequest) { // We're blocking the plugin waiting for a response. if(parsed.hasValue("blocking_response")) { // This is the message we've been waiting for -- fall through and send it immediately. mBlockingResponseReceived = true; } else { // Still waiting. Queue this message and don't process it yet. mMessageQueue.push(message); return; } } bool passMessage = true; // FIXME: how should we handle queueing here? { std::string message_class = parsed.getClass(); if(message_class == LLPLUGIN_MESSAGE_CLASS_INTERNAL) { passMessage = false; std::string message_name = parsed.getName(); if(message_name == "load_plugin") { mPluginFile = parsed.getValue("file"); mPluginDir = parsed.getValue("dir"); } else if(message_name == "shm_add") { std::string name = parsed.getValue("name"); size_t size = (size_t)parsed.getValueS32("size"); sharedMemoryRegionsType::iterator iter = mSharedMemoryRegions.find(name); if(iter != mSharedMemoryRegions.end()) { // Need to remove the old region first LL_WARNS("PluginChild") << "Adding a duplicate shared memory segment!" << LL_ENDL; } else { // This is a new region LLPluginSharedMemory *region = new LLPluginSharedMemory; if(region->attach(name, size)) { mSharedMemoryRegions.insert(sharedMemoryRegionsType::value_type(name, region)); std::stringstream addr; addr << region->getMappedAddress(); // Send the add notification to the plugin LLPluginMessage message("base", "shm_added"); message.setValue("name", name); message.setValueS32("size", (S32)size); message.setValuePointer("address", region->getMappedAddress()); sendMessageToPlugin(message); // and send the response to the parent message.setMessage(LLPLUGIN_MESSAGE_CLASS_INTERNAL, "shm_add_response"); message.setValue("name", name); sendMessageToParent(message); } else { LL_WARNS("PluginChild") << "Couldn't create a shared memory segment!" << LL_ENDL; delete region; } } } else if(message_name == "shm_remove") { std::string name = parsed.getValue("name"); sharedMemoryRegionsType::iterator iter = mSharedMemoryRegions.find(name); if(iter != mSharedMemoryRegions.end()) { // forward the remove request to the plugin -- its response will trigger us to detach the segment. LLPluginMessage message("base", "shm_remove"); message.setValue("name", name); sendMessageToPlugin(message); } else { LL_WARNS("PluginChild") << "shm_remove for unknown memory segment!" << LL_ENDL; } } else if(message_name == "sleep_time") { mSleepTime = llmax(parsed.getValueReal("time"), 1.0 / 100.0); // clamp to maximum of 100Hz } #if LL_WINDOWS else if(message_name == "show_console") { createConsole(); } #endif else if(message_name == "crash") { // Crash the plugin LL_ERRS("PluginChild") << "Plugin crash requested." << LL_ENDL; } else if(message_name == "hang") { // Hang the plugin LL_WARNS("PluginChild") << "Plugin hang requested." << LL_ENDL; while(1) { // wheeeeeeeee...... } } else { LL_WARNS("PluginChild") << "Unknown internal message from parent: " << message_name << LL_ENDL; } } } if(passMessage && mInstance != NULL) { LLTimer elapsed; mInstance->sendMessage(message); mCPUElapsed += elapsed.getElapsedTimeF64(); } }
/*virtual*/ void LLClassifiedStatsResponder::httpFailure() { LL_WARNS() << dumpResponse() << LL_ENDL; }
BOOL LLDXHardware::getInfo(BOOL vram_only) { LLTimer hw_timer; BOOL ok = FALSE; HRESULT hr; CoInitialize(NULL); IDxDiagProvider *dx_diag_providerp = NULL; IDxDiagContainer *dx_diag_rootp = NULL; IDxDiagContainer *devices_containerp = NULL; // IDxDiagContainer *system_device_containerp= NULL; IDxDiagContainer *device_containerp = NULL; IDxDiagContainer *file_containerp = NULL; IDxDiagContainer *driver_containerp = NULL; // CoCreate a IDxDiagProvider* LL_DEBUGS("AppInit") << "CoCreateInstance IID_IDxDiagProvider" << LL_ENDL; hr = CoCreateInstance(CLSID_DxDiagProvider, NULL, CLSCTX_INPROC_SERVER, IID_IDxDiagProvider, (LPVOID*) &dx_diag_providerp); if (FAILED(hr)) { LL_WARNS("AppInit") << "No DXDiag provider found! DirectX 9 not installed!" << LL_ENDL; gWriteDebug("No DXDiag provider found! DirectX 9 not installed!\n"); goto LCleanup; } if (SUCCEEDED(hr)) // if FAILED(hr) then dx9 is not installed { // Fill out a DXDIAG_INIT_PARAMS struct and pass it to IDxDiagContainer::Initialize // Passing in TRUE for bAllowWHQLChecks, allows dxdiag to check if drivers are // digital signed as logo'd by WHQL which may connect via internet to update // WHQL certificates. DXDIAG_INIT_PARAMS dx_diag_init_params; ZeroMemory(&dx_diag_init_params, sizeof(DXDIAG_INIT_PARAMS)); dx_diag_init_params.dwSize = sizeof(DXDIAG_INIT_PARAMS); dx_diag_init_params.dwDxDiagHeaderVersion = DXDIAG_DX9_SDK_VERSION; dx_diag_init_params.bAllowWHQLChecks = TRUE; dx_diag_init_params.pReserved = NULL; LL_DEBUGS("AppInit") << "dx_diag_providerp->Initialize" << LL_ENDL; hr = dx_diag_providerp->Initialize(&dx_diag_init_params); if(FAILED(hr)) { goto LCleanup; } LL_DEBUGS("AppInit") << "dx_diag_providerp->GetRootContainer" << LL_ENDL; hr = dx_diag_providerp->GetRootContainer( &dx_diag_rootp ); if(FAILED(hr) || !dx_diag_rootp) { goto LCleanup; } HRESULT hr; // Get display driver information LL_DEBUGS("AppInit") << "dx_diag_rootp->GetChildContainer" << LL_ENDL; hr = dx_diag_rootp->GetChildContainer(L"DxDiag_DisplayDevices", &devices_containerp); if(FAILED(hr) || !devices_containerp) { goto LCleanup; } // Get device 0 LL_DEBUGS("AppInit") << "devices_containerp->GetChildContainer" << LL_ENDL; hr = devices_containerp->GetChildContainer(L"0", &device_containerp); if(FAILED(hr) || !device_containerp) { goto LCleanup; } // Get the English VRAM string { std::string ram_str = get_string(device_containerp, L"szDisplayMemoryEnglish"); // We don't need the device any more SAFE_RELEASE(device_containerp); // Dump the string as an int into the structure char *stopstring; mVRAM = strtol(ram_str.c_str(), &stopstring, 10); LL_INFOS("AppInit") << "VRAM Detected: " << mVRAM << " DX9 string: " << ram_str << LL_ENDL; } if (vram_only) { ok = TRUE; goto LCleanup; } /* for now, we ONLY do vram_only the rest of this is commented out, to ensure no-one is tempted to use it // Now let's get device and driver information // Get the IDxDiagContainer object called "DxDiag_SystemDevices". // This call may take some time while dxdiag gathers the info. DWORD num_devices = 0; WCHAR wszContainer[256]; LL_DEBUGS("AppInit") << "dx_diag_rootp->GetChildContainer DxDiag_SystemDevices" << LL_ENDL; hr = dx_diag_rootp->GetChildContainer(L"DxDiag_SystemDevices", &system_device_containerp); if (FAILED(hr)) { goto LCleanup; } hr = system_device_containerp->GetNumberOfChildContainers(&num_devices); if (FAILED(hr)) { goto LCleanup; } LL_DEBUGS("AppInit") << "DX9 iterating over devices" << LL_ENDL; S32 device_num = 0; for (device_num = 0; device_num < (S32)num_devices; device_num++) { hr = system_device_containerp->EnumChildContainerNames(device_num, wszContainer, 256); if (FAILED(hr)) { goto LCleanup; } hr = system_device_containerp->GetChildContainer(wszContainer, &device_containerp); if (FAILED(hr) || device_containerp == NULL) { goto LCleanup; } std::string device_name = get_string(device_containerp, L"szDescription"); std::string device_id = get_string(device_containerp, L"szDeviceID"); LLDXDevice *dxdevicep = new LLDXDevice; dxdevicep->mName = device_name; dxdevicep->mPCIString = device_id; mDevices[dxdevicep->mPCIString] = dxdevicep; // Split the PCI string based on vendor, device, subsys, rev. std::string str(device_id); typedef boost::tokenizer<boost::char_separator<char> > tokenizer; boost::char_separator<char> sep("&\\", "", boost::keep_empty_tokens); tokenizer tokens(str, sep); tokenizer::iterator iter = tokens.begin(); S32 count = 0; BOOL valid = TRUE; for (;(iter != tokens.end()) && (count < 3);++iter) { switch (count) { case 0: if (strcmp(iter->c_str(), "PCI")) { valid = FALSE; } break; case 1: dxdevicep->mVendorID = iter->c_str(); break; case 2: dxdevicep->mDeviceID = iter->c_str(); break; default: // Ignore it break; } count++; } // Now, iterate through the related drivers hr = device_containerp->GetChildContainer(L"Drivers", &driver_containerp); if (FAILED(hr) || !driver_containerp) { goto LCleanup; } DWORD num_files = 0; hr = driver_containerp->GetNumberOfChildContainers(&num_files); if (FAILED(hr)) { goto LCleanup; } S32 file_num = 0; for (file_num = 0; file_num < (S32)num_files; file_num++ ) { hr = driver_containerp->EnumChildContainerNames(file_num, wszContainer, 256); if (FAILED(hr)) { goto LCleanup; } hr = driver_containerp->GetChildContainer(wszContainer, &file_containerp); if (FAILED(hr) || file_containerp == NULL) { goto LCleanup; } std::string driver_path = get_string(file_containerp, L"szPath"); std::string driver_name = get_string(file_containerp, L"szName"); std::string driver_version = get_string(file_containerp, L"szVersion"); std::string driver_date = get_string(file_containerp, L"szDatestampEnglish"); LLDXDriverFile *dxdriverfilep = new LLDXDriverFile; dxdriverfilep->mName = driver_name; dxdriverfilep->mFilepath= driver_path; dxdriverfilep->mVersionString = driver_version; dxdriverfilep->mVersion.set(driver_version); dxdriverfilep->mDateString = driver_date; dxdevicep->mDriverFiles[driver_name] = dxdriverfilep; SAFE_RELEASE(file_containerp); } SAFE_RELEASE(device_containerp); } */ } // dumpDevices(); ok = TRUE; LCleanup: if (!ok) { LL_WARNS("AppInit") << "DX9 probe failed" << LL_ENDL; gWriteDebug("DX9 probe failed\n"); } SAFE_RELEASE(file_containerp); SAFE_RELEASE(driver_containerp); SAFE_RELEASE(device_containerp); SAFE_RELEASE(devices_containerp); SAFE_RELEASE(dx_diag_rootp); SAFE_RELEASE(dx_diag_providerp); CoUninitialize(); return ok; }
/*virtual*/ void httpFailure() { LL_WARNS() << "experience responder failed [status:" << getStatus() << "]: " << getContent() << LL_ENDL; }
void LLDrawable::shiftPos(const LLVector4a &shift_vector) { if (isDead()) { LL_WARNS() << "Shifting dead drawable" << LL_ENDL; return; } if (mParent) { mXform.setPosition(mVObjp->getPosition()); } else { mXform.setPosition(mVObjp->getPositionAgent()); } mXform.updateMatrix(); if (isStatic()) { LLVOVolume* volume = getVOVolume(); bool rebuild = (!volume && getRenderType() != LLPipeline::RENDER_TYPE_TREE && getRenderType() != LLPipeline::RENDER_TYPE_TERRAIN && getRenderType() != LLPipeline::RENDER_TYPE_SKY && getRenderType() != LLPipeline::RENDER_TYPE_GROUND); if (rebuild) { gPipeline.markRebuild(this, LLDrawable::REBUILD_ALL, TRUE); } for (S32 i = 0; i < getNumFaces(); i++) { LLFace *facep = getFace(i); if (facep) { facep->mCenterAgent += LLVector3(shift_vector.getF32ptr()); facep->mExtents[0].add(shift_vector); facep->mExtents[1].add(shift_vector); if (rebuild && facep->hasGeometry()) { facep->clearVertexBuffer(); } } } shift(shift_vector); } else if (mSpatialBridge) { mSpatialBridge->shiftPos(shift_vector); } else if (isAvatar()) { shift(shift_vector); } mVObjp->onShift(shift_vector); }
// Called instead of exit() if Libjpeg encounters an error. void on_jpeg_error(j_common_ptr cinfo) { (void) cinfo; sJpegErrorEncountered = true; LL_WARNS() << "Libjpeg has encountered an error!" << LL_ENDL; }
BOOL LLVOPartGroup::updateGeometry(LLDrawable *drawable) { LL_RECORD_BLOCK_TIME(FTM_UPDATE_PARTICLES); dirtySpatialGroup(); S32 num_parts = mViewerPartGroupp->getCount(); LLFace *facep; LLSpatialGroup* group = drawable->getSpatialGroup(); if (!group && num_parts) { drawable->movePartition(); group = drawable->getSpatialGroup(); } if (group && group->isVisible()) { dirtySpatialGroup(TRUE); } if (!num_parts) { if (group && drawable->getNumFaces()) { group->setState(LLSpatialGroup::GEOM_DIRTY); } drawable->setNumFaces(0, NULL, getTEImage(0)); LLPipeline::sCompiles++; return TRUE; } if (!(gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_PARTICLES))) { return TRUE; } if (num_parts > drawable->getNumFaces()) { drawable->setNumFacesFast(num_parts+num_parts/4, NULL, getTEImage(0)); } F32 tot_area = 0; F32 max_area = LLViewerPartSim::getMaxPartCount() * MAX_PARTICLE_AREA_SCALE; F32 pixel_meter_ratio = LLViewerCamera::getInstance()->getPixelMeterRatio(); pixel_meter_ratio *= pixel_meter_ratio; LLViewerPartSim::checkParticleCount(mViewerPartGroupp->mParticles.size()) ; S32 count=0; mDepth = 0.f; S32 i = 0 ; LLVector3 camera_agent = getCameraPosition(); F32 max_scale = 0.f; for (i = 0 ; i < (S32)mViewerPartGroupp->mParticles.size(); i++) { const LLViewerPart *part = mViewerPartGroupp->mParticles[i]; //remember the largest particle max_scale = llmax(max_scale, part->mScale.mV[0], part->mScale.mV[1]); if (part->mFlags & LLPartData::LL_PART_RIBBON_MASK) { //include ribbon segment length in scale const LLVector3* pos_agent = NULL; if (part->mParent) { pos_agent = &(part->mParent->mPosAgent); } else if (part->mPartSourcep.notNull()) { pos_agent = &(part->mPartSourcep->mPosAgent); } if (pos_agent) { F32 dist = (*pos_agent-part->mPosAgent).length(); max_scale = llmax(max_scale, dist); } } LLVector3 part_pos_agent(part->mPosAgent); LLVector3 at(part_pos_agent - camera_agent); F32 camera_dist_squared = at.lengthSquared(); F32 inv_camera_dist_squared; if (camera_dist_squared > 1.f) inv_camera_dist_squared = 1.f / camera_dist_squared; else inv_camera_dist_squared = 1.f; llassert(llfinite(inv_camera_dist_squared)); llassert(!llisnan(inv_camera_dist_squared)); F32 area = part->mScale.mV[0] * part->mScale.mV[1] * inv_camera_dist_squared; tot_area = llmax(tot_area, area); if (tot_area > max_area) { break; } count++; facep = drawable->getFace(i); if (!facep) { LL_WARNS() << "No face found for index " << i << "!" << LL_ENDL; continue; } facep->setTEOffset(i); const F32 NEAR_PART_DIST_SQ = 5.f*5.f; // Only discard particles > 5 m from the camera const F32 MIN_PART_AREA = .005f*.005f; // only less than 5 mm x 5 mm at 1 m from camera if (camera_dist_squared > NEAR_PART_DIST_SQ && area < MIN_PART_AREA) { facep->setSize(0, 0); continue; } facep->setSize(4, 6); facep->setViewerObject(this); if (part->mFlags & LLPartData::LL_PART_EMISSIVE_MASK) { facep->setState(LLFace::FULLBRIGHT); } else { facep->clearState(LLFace::FULLBRIGHT); } facep->mCenterLocal = part->mPosAgent; facep->setFaceColor(part->mColor); facep->setTexture(part->mImagep); //check if this particle texture is replaced by a parcel media texture. if(part->mImagep.notNull() && part->mImagep->hasParcelMedia()) { part->mImagep->getParcelMedia()->addMediaToFace(facep) ; } mPixelArea = tot_area * pixel_meter_ratio; const F32 area_scale = 10.f; // scale area to increase priority a bit facep->setVirtualSize(mPixelArea*area_scale); } for (i = count; i < drawable->getNumFaces(); i++) { LLFace* facep = drawable->getFace(i); if (!facep) { LL_WARNS() << "No face found for index " << i << "!" << LL_ENDL; continue; } facep->setTEOffset(i); facep->setSize(0, 0); } //record max scale (used to stretch bounding box for visibility culling) mScale.set(max_scale, max_scale, max_scale); mDrawable->movePartition(); LLPipeline::sCompiles++; return TRUE; }
//////////////////////////////////////////////////////////////////////////////// // inherited from LLViewerMediaObserver //virtual void LLMediaCtrl::handleMediaEvent(LLPluginClassMedia* self, EMediaEvent event) { switch(event) { case MEDIA_EVENT_CONTENT_UPDATED: { // LL_DEBUGS("Media") << "Media event: MEDIA_EVENT_CONTENT_UPDATED " << LL_ENDL; }; break; case MEDIA_EVENT_TIME_DURATION_UPDATED: { // LL_DEBUGS("Media") << "Media event: MEDIA_EVENT_TIME_DURATION_UPDATED, time is " << self->getCurrentTime() << " of " << self->getDuration() << LL_ENDL; }; break; case MEDIA_EVENT_SIZE_CHANGED: { LL_DEBUGS("Media") << "Media event: MEDIA_EVENT_SIZE_CHANGED " << LL_ENDL; LLRect r = getRect(); reshape( r.getWidth(), r.getHeight(), FALSE ); }; break; case MEDIA_EVENT_CURSOR_CHANGED: { LL_INFOS("Media") << "Media event: MEDIA_EVENT_CURSOR_CHANGED, new cursor is " << self->getCursorName() << LL_ENDL; std::string cursor = self->getCursorName(); if(cursor == "arrow") mLastSetCursor = UI_CURSOR_ARROW; else if(cursor == "ibeam") mLastSetCursor = UI_CURSOR_IBEAM; else if(cursor == "splith") mLastSetCursor = UI_CURSOR_SIZEWE; else if(cursor == "splitv") mLastSetCursor = UI_CURSOR_SIZENS; else if(cursor == "hand") mLastSetCursor = UI_CURSOR_HAND; else // for anything else, default to the arrow mLastSetCursor = UI_CURSOR_ARROW; }; break; case MEDIA_EVENT_NAVIGATE_BEGIN: { LL_INFOS("Media") << "Media event: MEDIA_EVENT_NAVIGATE_BEGIN, url is " << self->getNavigateURI() << LL_ENDL; }; break; case MEDIA_EVENT_NAVIGATE_COMPLETE: { LL_INFOS("Media") << "Media event: MEDIA_EVENT_NAVIGATE_COMPLETE, result string is: " << self->getNavigateResultString() << LL_ENDL; if(mHidingInitialLoad) { mHidingInitialLoad = false; } }; break; case MEDIA_EVENT_PROGRESS_UPDATED: { LL_DEBUGS("Media") << "Media event: MEDIA_EVENT_PROGRESS_UPDATED, loading at " << self->getProgressPercent() << "%" << LL_ENDL; }; break; case MEDIA_EVENT_STATUS_TEXT_CHANGED: { LL_DEBUGS("Media") << "Media event: MEDIA_EVENT_STATUS_TEXT_CHANGED, new status text is: " << self->getStatusText() << LL_ENDL; }; break; case MEDIA_EVENT_LOCATION_CHANGED: { LL_DEBUGS("Media") << "Media event: MEDIA_EVENT_LOCATION_CHANGED, new uri is: " << self->getLocation() << LL_ENDL; }; break; case MEDIA_EVENT_NAVIGATE_ERROR_PAGE: { LL_DEBUGS("Media") << "Media event: MEDIA_EVENT_NAVIGATE_ERROR_PAGE" << LL_ENDL; if (mErrorPageURL.length() > 0) { navigateTo(mErrorPageURL, "text/html"); }; }; break; case MEDIA_EVENT_CLICK_LINK_HREF: { LL_DEBUGS("Media") << "Media event: MEDIA_EVENT_CLICK_LINK_HREF, target is \"" << self->getClickTarget() << "\", uri is " << self->getClickURL() << LL_ENDL; }; break; case MEDIA_EVENT_CLICK_LINK_NOFOLLOW: { LL_DEBUGS("Media") << "Media event: MEDIA_EVENT_CLICK_LINK_NOFOLLOW, uri is " << self->getClickURL() << LL_ENDL; onClickLinkNoFollow(self); }; break; case MEDIA_EVENT_PLUGIN_FAILED: { LL_DEBUGS("Media") << "Media event: MEDIA_EVENT_PLUGIN_FAILED" << LL_ENDL; }; break; case MEDIA_EVENT_PLUGIN_FAILED_LAUNCH: { LL_DEBUGS("Media") << "Media event: MEDIA_EVENT_PLUGIN_FAILED_LAUNCH" << LL_ENDL; }; break; case MEDIA_EVENT_NAME_CHANGED: { LL_DEBUGS("Media") << "Media event: MEDIA_EVENT_NAME_CHANGED" << LL_ENDL; }; break; case MEDIA_EVENT_CLOSE_REQUEST: { LL_DEBUGS("Media") << "Media event: MEDIA_EVENT_CLOSE_REQUEST" << LL_ENDL; } break; case MEDIA_EVENT_PICK_FILE_REQUEST: { LL_DEBUGS("Media") << "Media event: MEDIA_EVENT_PICK_FILE_REQUEST" << LL_ENDL; } break; case MEDIA_EVENT_GEOMETRY_CHANGE: { LL_DEBUGS("Media") << "Media event: MEDIA_EVENT_GEOMETRY_CHANGE, uuid is " << self->getClickUUID() << LL_ENDL; } break; case MEDIA_EVENT_STATUS_CHANGED: { LL_DEBUGS("Media") << "Media event: MEDIA_EVENT_STATUS_CHANGED" << LL_ENDL; } break; case MEDIA_EVENT_AUTH_REQUEST: { LL_WARNS("Media") << "Unimplemented Media event: MEDIA_EVENT_AUTH_REQUEST" << LL_ENDL; }; break; case MEDIA_EVENT_LINK_HOVERED: { LL_WARNS("Media") << "Unimplemented Media event: MEDIA_EVENT_LINK_HOVERED" << LL_ENDL; }; break; }; // chain all events to any potential observers of this object. emitEvent(self, event); }
void LLPluginProcessParent::updatePollset() { if(!sInstancesMutex) { // No instances have been created yet. There's no work to do. return; } LLMutexLock lock(sInstancesMutex); if(sPollSet) { LL_DEBUGS("PluginPoll") << "destroying pollset " << sPollSet << LL_ENDL; // delete the existing pollset. apr_pollset_destroy(sPollSet); sPollSet = NULL; } std::list<LLPluginProcessParent*>::iterator iter; int count = 0; // Count the number of instances that want to be in the pollset for(iter = sInstances.begin(); iter != sInstances.end(); iter++) { (*iter)->mPolledInput = false; if((*iter)->mPollFD.client_data) { // This instance has a socket that needs to be polled. ++count; } } if(sUseReadThread && sReadThread && !sReadThread->isQuitting()) { if(!sPollSet && (count > 0)) { #ifdef APR_POLLSET_NOCOPY // The pollset doesn't exist yet. Create it now. apr_status_t status = apr_pollset_create(&sPollSet, count, gAPRPoolp, APR_POLLSET_NOCOPY); if(status != APR_SUCCESS) { #endif // APR_POLLSET_NOCOPY LL_WARNS("PluginPoll") << "Couldn't create pollset. Falling back to non-pollset mode." << LL_ENDL; sPollSet = NULL; #ifdef APR_POLLSET_NOCOPY } else { LL_DEBUGS("PluginPoll") << "created pollset " << sPollSet << LL_ENDL; // Pollset was created, add all instances to it. for(iter = sInstances.begin(); iter != sInstances.end(); iter++) { if((*iter)->mPollFD.client_data) { status = apr_pollset_add(sPollSet, &((*iter)->mPollFD)); if(status == APR_SUCCESS) { (*iter)->mPolledInput = true; } else { LL_WARNS("PluginPoll") << "apr_pollset_add failed with status " << status << LL_ENDL; } } } } #endif // APR_POLLSET_NOCOPY } } }
LLLocationInputCtrl::LLLocationInputCtrl(const LLLocationInputCtrl::Params& p) : LLComboBox(p), mIconHPad(p.icon_hpad), mAddLandmarkHPad(p.add_landmark_hpad), mLocationContextMenu(NULL), mAddLandmarkBtn(NULL), mForSaleBtn(NULL), mInfoBtn(NULL), mRegionCrossingSlot(), mNavMeshSlot(), mIsNavMeshDirty(false), mLandmarkImageOn(NULL), mLandmarkImageOff(NULL), mIconMaturityGeneral(NULL), mIconMaturityAdult(NULL), mIconMaturityModerate(NULL), mMaturityHelpTopic(p.maturity_help_topic) { // Lets replace default LLLineEditor with LLLocationLineEditor // to make needed escaping while copying and cutting url delete mTextEntry; // Can't access old mTextEntry fields as they are protected, so lets build new params // That is C&P from LLComboBox::createLineEditor function static LLUICachedControl<S32> drop_shadow_button ("DropShadowButton", 0); S32 arrow_width = mArrowImage ? mArrowImage->getWidth() : 0; LLRect text_entry_rect(0, getRect().getHeight(), getRect().getWidth(), 0); text_entry_rect.mRight -= llmax(8,arrow_width) + 2 * drop_shadow_button; LLLineEditor::Params params = p.combo_editor; params.rect(text_entry_rect); params.default_text(LLStringUtil::null); params.max_length.bytes(p.max_chars); params.keystroke_callback(boost::bind(&LLLocationInputCtrl::onTextEntry, this, _1)); params.commit_on_focus_lost(false); params.follows.flags(FOLLOWS_ALL); mTextEntry = LLUICtrlFactory::create<LLURLLineEditor>(params); mTextEntry->setContextMenu(NULL); addChild(mTextEntry); // LLLineEditor is replaced with LLLocationLineEditor // "Place information" button. LLButton::Params info_params = p.info_button; mInfoBtn = LLUICtrlFactory::create<LLButton>(info_params); mInfoBtn->setClickedCallback(boost::bind(&LLLocationInputCtrl::onInfoButtonClicked, this)); addChild(mInfoBtn); // "Add landmark" button. LLButton::Params al_params = p.add_landmark_button; // Image for unselected state will be set in updateAddLandmarkButton(), // it will be either mLandmarkOn or mLandmarkOff if (p.add_landmark_image_enabled()) { mLandmarkImageOn = p.add_landmark_image_enabled; } if (p.add_landmark_image_disabled()) { mLandmarkImageOff = p.add_landmark_image_disabled; } if(p.add_landmark_image_selected) { al_params.image_selected = p.add_landmark_image_selected; } if (p.add_landmark_image_hover()) { al_params.image_hover_unselected = p.add_landmark_image_hover; } al_params.click_callback.function(boost::bind(&LLLocationInputCtrl::onAddLandmarkButtonClicked, this)); mAddLandmarkBtn = LLUICtrlFactory::create<LLButton>(al_params); enableAddLandmarkButton(true); addChild(mAddLandmarkBtn); if (p.icon_maturity_general()) { mIconMaturityGeneral = p.icon_maturity_general; } if (p.icon_maturity_adult()) { mIconMaturityAdult = p.icon_maturity_adult; } if(p.icon_maturity_moderate()) { mIconMaturityModerate = p.icon_maturity_moderate; } LLButton::Params maturity_button = p.maturity_button; mMaturityButton = LLUICtrlFactory::create<LLButton>(maturity_button); addChild(mMaturityButton); mMaturityButton->setClickedCallback(boost::bind(&LLLocationInputCtrl::onMaturityButtonClicked, this)); LLButton::Params for_sale_button = p.for_sale_button; for_sale_button.tool_tip = LLTrans::getString("LocationCtrlForSaleTooltip"); for_sale_button.click_callback.function( boost::bind(&LLLocationInputCtrl::onForSaleButtonClicked, this)); mForSaleBtn = LLUICtrlFactory::create<LLButton>( for_sale_button ); addChild(mForSaleBtn); // Parcel property icons // Must be mouse-opaque so cursor stays as an arrow when hovering to // see tooltip. LLIconCtrl::Params voice_icon = p.voice_icon; voice_icon.tool_tip = LLTrans::getString("LocationCtrlVoiceTooltip"); voice_icon.mouse_opaque = true; mParcelIcon[VOICE_ICON] = LLUICtrlFactory::create<LLIconCtrl>(voice_icon); mParcelIcon[VOICE_ICON]->setMouseDownCallback(boost::bind(&LLLocationInputCtrl::onParcelIconClick, this, VOICE_ICON)); addChild(mParcelIcon[VOICE_ICON]); LLIconCtrl::Params fly_icon = p.fly_icon; fly_icon.tool_tip = LLTrans::getString("LocationCtrlFlyTooltip"); fly_icon.mouse_opaque = true; mParcelIcon[FLY_ICON] = LLUICtrlFactory::create<LLIconCtrl>(fly_icon); mParcelIcon[FLY_ICON]->setMouseDownCallback(boost::bind(&LLLocationInputCtrl::onParcelIconClick, this, FLY_ICON)); addChild(mParcelIcon[FLY_ICON]); LLIconCtrl::Params push_icon = p.push_icon; push_icon.tool_tip = LLTrans::getString("LocationCtrlPushTooltip"); push_icon.mouse_opaque = true; mParcelIcon[PUSH_ICON] = LLUICtrlFactory::create<LLIconCtrl>(push_icon); mParcelIcon[PUSH_ICON]->setMouseDownCallback(boost::bind(&LLLocationInputCtrl::onParcelIconClick, this, PUSH_ICON)); addChild(mParcelIcon[PUSH_ICON]); LLIconCtrl::Params build_icon = p.build_icon; build_icon.tool_tip = LLTrans::getString("LocationCtrlBuildTooltip"); build_icon.mouse_opaque = true; mParcelIcon[BUILD_ICON] = LLUICtrlFactory::create<LLIconCtrl>(build_icon); mParcelIcon[BUILD_ICON]->setMouseDownCallback(boost::bind(&LLLocationInputCtrl::onParcelIconClick, this, BUILD_ICON)); addChild(mParcelIcon[BUILD_ICON]); LLIconCtrl::Params scripts_icon = p.scripts_icon; scripts_icon.tool_tip = LLTrans::getString("LocationCtrlScriptsTooltip"); scripts_icon.mouse_opaque = true; mParcelIcon[SCRIPTS_ICON] = LLUICtrlFactory::create<LLIconCtrl>(scripts_icon); mParcelIcon[SCRIPTS_ICON]->setMouseDownCallback(boost::bind(&LLLocationInputCtrl::onParcelIconClick, this, SCRIPTS_ICON)); addChild(mParcelIcon[SCRIPTS_ICON]); LLIconCtrl::Params damage_icon = p.damage_icon; damage_icon.tool_tip = LLTrans::getString("LocationCtrlDamageTooltip"); damage_icon.mouse_opaque = true; mParcelIcon[DAMAGE_ICON] = LLUICtrlFactory::create<LLIconCtrl>(damage_icon); mParcelIcon[DAMAGE_ICON]->setMouseDownCallback(boost::bind(&LLLocationInputCtrl::onParcelIconClick, this, DAMAGE_ICON)); addChild(mParcelIcon[DAMAGE_ICON]); LLIconCtrl::Params pathfinding_dirty_icon = p.pathfinding_dirty_icon; pathfinding_dirty_icon.tool_tip = LLTrans::getString("LocationCtrlPathfindingDirtyTooltip"); pathfinding_dirty_icon.mouse_opaque = true; mParcelIcon[PATHFINDING_DIRTY_ICON] = LLUICtrlFactory::create<LLIconCtrl>(pathfinding_dirty_icon); mParcelIcon[PATHFINDING_DIRTY_ICON]->setMouseDownCallback(boost::bind(&LLLocationInputCtrl::onParcelIconClick, this, PATHFINDING_DIRTY_ICON)); addChild(mParcelIcon[PATHFINDING_DIRTY_ICON]); LLIconCtrl::Params pathfinding_disabled_icon = p.pathfinding_disabled_icon; pathfinding_disabled_icon.tool_tip = LLTrans::getString("LocationCtrlPathfindingDisabledTooltip"); pathfinding_disabled_icon.mouse_opaque = true; mParcelIcon[PATHFINDING_DISABLED_ICON] = LLUICtrlFactory::create<LLIconCtrl>(pathfinding_disabled_icon); mParcelIcon[PATHFINDING_DISABLED_ICON]->setMouseDownCallback(boost::bind(&LLLocationInputCtrl::onParcelIconClick, this, PATHFINDING_DISABLED_ICON)); addChild(mParcelIcon[PATHFINDING_DISABLED_ICON]); LLTextBox::Params damage_text = p.damage_text; damage_text.tool_tip = LLTrans::getString("LocationCtrlDamageTooltip"); damage_text.mouse_opaque = true; mDamageText = LLUICtrlFactory::create<LLTextBox>(damage_text); addChild(mDamageText); LLIconCtrl::Params see_avatars_icon = p.see_avatars_icon; see_avatars_icon.tool_tip = LLTrans::getString("LocationCtrlSeeAVsTooltip"); see_avatars_icon.mouse_opaque = true; mParcelIcon[SEE_AVATARS_ICON] = LLUICtrlFactory::create<LLIconCtrl>(see_avatars_icon); mParcelIcon[SEE_AVATARS_ICON]->setMouseDownCallback(boost::bind(&LLLocationInputCtrl::onParcelIconClick, this, SEE_AVATARS_ICON)); addChild(mParcelIcon[SEE_AVATARS_ICON]); // Register callbacks and load the location field context menu (NB: the order matters). LLUICtrl::CommitCallbackRegistry::currentRegistrar().add("Navbar.Action", boost::bind(&LLLocationInputCtrl::onLocationContextMenuItemClicked, this, _2)); LLUICtrl::EnableCallbackRegistry::currentRegistrar().add("Navbar.EnableMenuItem", boost::bind(&LLLocationInputCtrl::onLocationContextMenuItemEnabled, this, _2)); setPrearrangeCallback(boost::bind(&LLLocationInputCtrl::onLocationPrearrange, this, _2)); getTextEntry()->setMouseUpCallback(boost::bind(&LLLocationInputCtrl::changeLocationPresentation, this)); // Load the location field context menu mLocationContextMenu = LLUICtrlFactory::getInstance()->createFromFile<LLMenuGL>("menu_navbar.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance()); if (!mLocationContextMenu) { LL_WARNS() << "Error loading navigation bar context menu" << LL_ENDL; } getTextEntry()->setRightMouseUpCallback(boost::bind(&LLLocationInputCtrl::onTextEditorRightClicked,this,_2,_3,_4)); updateWidgetlayout(); // Connecting signal for updating location on "Show Coordinates" setting change. LLControlVariable* coordinates_control = gSavedSettings.getControl("NavBarShowCoordinates").get(); if (coordinates_control) { mCoordinatesControlConnection = coordinates_control->getSignal()->connect(boost::bind(&LLLocationInputCtrl::refreshLocation, this)); } // Connecting signal for updating parcel icons on "Show Parcel Properties" setting change. LLControlVariable* parcel_properties_control = gSavedSettings.getControl("NavBarShowParcelProperties").get(); if (parcel_properties_control) { mParcelPropertiesControlConnection = parcel_properties_control->getSignal()->connect(boost::bind(&LLLocationInputCtrl::refreshParcelIcons, this)); } // - Make the "Add landmark" button updated when either current parcel gets changed // or a landmark gets created or removed from the inventory. // - Update the location string on parcel change. mParcelMgrConnection = gAgent.addParcelChangedCallback( boost::bind(&LLLocationInputCtrl::onAgentParcelChange, this)); // LLLocationHistory instance is being created before the location input control, so we have to update initial state of button manually. mButton->setEnabled(LLLocationHistory::instance().getItemCount() > 0); mLocationHistoryConnection = LLLocationHistory::getInstance()->setChangedCallback( boost::bind(&LLLocationInputCtrl::onLocationHistoryChanged, this,_1)); mRegionCrossingSlot = gAgent.addRegionChangedCallback(boost::bind(&LLLocationInputCtrl::onRegionBoundaryCrossed, this)); createNavMeshStatusListenerForCurrentRegion(); mRemoveLandmarkObserver = new LLRemoveLandmarkObserver(this); mAddLandmarkObserver = new LLAddLandmarkObserver(this); gInventory.addObserver(mRemoveLandmarkObserver); gInventory.addObserver(mAddLandmarkObserver); mParcelChangeObserver = new LLParcelChangeObserver(this); LLViewerParcelMgr::getInstance()->addObserver(mParcelChangeObserver); mAddLandmarkTooltip = LLTrans::getString("LocationCtrlAddLandmarkTooltip"); mEditLandmarkTooltip = LLTrans::getString("LocationCtrlEditLandmarkTooltip"); mButton->setToolTip(LLTrans::getString("LocationCtrlComboBtnTooltip")); mInfoBtn->setToolTip(LLTrans::getString("LocationCtrlInfoBtnTooltip")); // <FS:ND> Prevent querying LLTrans each frame mTooltips.push_back( LLTrans::getString("LocationCtrlGeneralIconTooltip") ); mTooltips.push_back( LLTrans::getString("LocationCtrlAdultIconTooltip") ); mTooltips.push_back( LLTrans::getString("LocationCtrlModerateIconTooltip") ); // </FS:ND> }
void LLPluginProcessParent::receiveMessage(const LLPluginMessage &message) { std::string message_class = message.getClass(); if(message_class == LLPLUGIN_MESSAGE_CLASS_INTERNAL) { // internal messages should be handled here std::string message_name = message.getName(); if(message_name == "hello") { if(mState == STATE_CONNECTED) { // Plugin host has launched. Tell it which plugin to load. setState(STATE_HELLO); } else { LL_WARNS("Plugin") << "received hello message in wrong state -- bailing out" << LL_ENDL; errorState(); } } else if(message_name == "load_plugin_response") { if(mState == STATE_LOADING) { // Plugin has been loaded. mPluginVersionString = message.getValue("plugin_version"); LL_INFOS("Plugin") << "plugin version string: " << mPluginVersionString << LL_ENDL; // Check which message classes/versions the plugin supports. // TODO: check against current versions // TODO: kill plugin on major mismatches? mMessageClassVersions = message.getValueLLSD("versions"); LLSD::map_iterator iter; for(iter = mMessageClassVersions.beginMap(); iter != mMessageClassVersions.endMap(); iter++) { LL_INFOS("Plugin") << "message class: " << iter->first << " -> version: " << iter->second.asString() << LL_ENDL; } // Send initial sleep time llassert_always(mSleepTime != 0.f); setSleepTime(mSleepTime, true); setState(STATE_RUNNING); } else { LL_WARNS("Plugin") << "received load_plugin_response message in wrong state -- bailing out" << LL_ENDL; errorState(); } } else if(message_name == "heartbeat") { // this resets our timer. mHeartbeat.setTimerExpirySec(mPluginLockupTimeout); mCPUUsage = message.getValueReal("cpu_usage"); LL_DEBUGS("Plugin") << "cpu usage reported as " << mCPUUsage << LL_ENDL; } else if(message_name == "shm_add_response") { // Nothing to do here. } else if(message_name == "shm_remove_response") { std::string name = message.getValue("name"); sharedMemoryRegionsType::iterator iter = mSharedMemoryRegions.find(name); if(iter != mSharedMemoryRegions.end()) { // destroy the shared memory region iter->second->destroy(); // and remove it from our map mSharedMemoryRegions.erase(iter); } } else { LL_WARNS("Plugin") << "Unknown internal message from child: " << message_name << LL_ENDL; } } else { if(mOwner != NULL) { mOwner->receivePluginMessage(message); } } }
// resolve a simstring from a slurl LLSLURL::LLSLURL(const std::string& slurl) { // by default we go to agni. mType = INVALID; if(slurl == SIM_LOCATION_HOME) { mType = HOME_LOCATION; } else if(slurl.empty() || (slurl == SIM_LOCATION_LAST)) { mType = LAST_LOCATION; } else { LLURI slurl_uri; // parse the slurl as a uri if(slurl.find(':') == std::string::npos) { // There may be no scheme ('secondlife:' etc.) passed in. In that case // we want to normalize the slurl by putting the appropriate scheme // in front of the slurl. So, we grab the appropriate slurl base // from the grid manager which may be http://slurl.com/secondlife/ for maingrid, or // https://<hostname>/region/ for Standalone grid (the word region, not the region name) // these slurls are typically passed in from the 'starting location' box on the login panel, // where the user can type in <regionname>/<x>/<y>/<z> std::string fixed_slurl = LLGridManager::getInstance()->getSLURLBase(); // the slurl that was passed in might have a prepended /, or not. So, // we strip off the prepended '/' so we don't end up with http://slurl.com/secondlife/<region>/<x>/<y>/<z> // or some such. if(slurl[0] == '/') { fixed_slurl += slurl.substr(1); } else { fixed_slurl += slurl; } // We then load the slurl into a LLURI form slurl_uri = LLURI(fixed_slurl); } else { // as we did have a scheme, implying a URI style slurl, we // simply parse it as a URI slurl_uri = LLURI(slurl); } LLSD path_array = slurl_uri.pathArray(); // determine whether it's a maingrid URI or an Standalone/open style URI // by looking at the scheme. If it's a 'secondlife:' slurl scheme or // 'sl:' scheme, we know it's maingrid // At the end of this if/else block, we'll have determined the grid, // and the slurl type (APP or LOCATION) if(slurl_uri.scheme() == LLSLURL::SLURL_SECONDLIFE_SCHEME) { // parse a maingrid style slurl. We know the grid is maingrid // so grab it. // A location slurl for maingrid (with the special schemes) can be in the form // secondlife://<regionname>/<x>/<y>/<z> // or // secondlife://<Grid>/secondlife/<region>/<x>/<y>/<z> // where if grid is empty, it specifies Agni // An app style slurl for maingrid can be // secondlife://<Grid>/app/<app parameters> // where an empty grid implies Agni // we'll start by checking the top of the 'path' which will be // either 'app', 'secondlife', or <x>. // default to maingrid mGrid = MAINGRID; if ((path_array[0].asString() == LLSLURL::SLURL_SECONDLIFE_PATH) || (path_array[0].asString() == LLSLURL::SLURL_APP_PATH)) { // it's in the form secondlife://<grid>/(app|secondlife) // so parse the grid name to derive the grid ID if (!slurl_uri.hostName().empty()) { mGrid = LLGridManager::getInstance()->getGridId(slurl_uri.hostName()); } else if(path_array[0].asString() == LLSLURL::SLURL_SECONDLIFE_PATH) { // If the slurl is in the form secondlife:///secondlife/<region> form, // then we are in fact on maingrid. mGrid = MAINGRID; } else if(path_array[0].asString() == LLSLURL::SLURL_APP_PATH) { // for app style slurls, where no grid name is specified, assume the currently // selected or logged in grid. mGrid = LLGridManager::getInstance()->getGridId(); } if(mGrid.empty()) { // we couldn't find the grid in the grid manager, so bail LL_WARNS("AppInit")<<"unable to find grid"<<LL_ENDL; return; } // set the type as appropriate. if(path_array[0].asString() == LLSLURL::SLURL_SECONDLIFE_PATH) { mType = LOCATION; } else { mType = APP; } path_array.erase(0); } else { // it wasn't a /secondlife/<region> or /app/<params>, so it must be secondlife://<region> // therefore the hostname will be the region name, and it's a location type mType = LOCATION; // 'normalize' it so the region name is in fact the head of the path_array path_array.insert(0, slurl_uri.hostName()); } } else if((slurl_uri.scheme() == LLSLURL::SLURL_HTTP_SCHEME) || (slurl_uri.scheme() == LLSLURL::SLURL_HTTPS_SCHEME) || (slurl_uri.scheme() == LLSLURL::SLURL_X_GRID_LOCATION_INFO_SCHEME)) { // We're dealing with either a Standalone style slurl or slurl.com slurl if ((slurl_uri.hostName() == LLSLURL::SLURL_COM) || (slurl_uri.hostName() == LLSLURL::WWW_SLURL_COM) || (slurl_uri.hostName() == LLSLURL::MAPS_SECONDLIFE_COM)) { // slurl.com implies maingrid mGrid = MAINGRID; } else { // Don't try to match any old http://<host>/ URL as a SLurl. // SLE SLurls will have the grid hostname in the URL, so only // match http URLs if the hostname matches the grid hostname // (or its a slurl.com or maps.secondlife.com URL). if ((slurl_uri.scheme() == LLSLURL::SLURL_HTTP_SCHEME || slurl_uri.scheme() == LLSLURL::SLURL_HTTPS_SCHEME) && slurl_uri.hostName() != LLGridManager::getInstance()->getGrid()) { return; } // As it's a Standalone grid/open, we will always have a hostname, as Standalone/open style // urls are properly formed, unlike the stinky maingrid style mGrid = slurl_uri.hostName(); } if (path_array.size() == 0) { // um, we need a path... return; } // we need to normalize the urls so // the path portion starts with the 'command' that we want to do // it can either be region or app. if ((path_array[0].asString() == LLSLURL::SLURL_REGION_PATH) || (path_array[0].asString() == LLSLURL::SLURL_SECONDLIFE_PATH)) { // strip off 'region' or 'secondlife' path_array.erase(0); // it's a location mType = LOCATION; } else if (path_array[0].asString() == LLSLURL::SLURL_APP_PATH) { mType = APP; path_array.erase(0); // leave app appended. } else { // not a valid https/http/x-grid-location-info slurl, so it'll likely just be a URL return; } } else { // invalid scheme, so bail return; } if(path_array.size() == 0) { // we gotta have some stuff after the specifier as to whether it's a region or command return; } // now that we know whether it's an app slurl or a location slurl, // parse the slurl into the proper data structures. if(mType == APP) { // grab the app command type and strip it (could be a command to jump somewhere, // or whatever ) mAppCmd = path_array[0].asString(); path_array.erase(0); // Grab the parameters mAppPath = path_array; // and the query mAppQuery = slurl_uri.query(); mAppQueryMap = slurl_uri.queryMap(); return; } else if(mType == LOCATION) { // at this point, head of the path array should be [ <region>, <x>, <y>, <z> ] where x, y and z // are collectively optional // are optional mRegion = LLURI::unescape(path_array[0].asString()); path_array.erase(0); // parse the x, y, and optionally z if(path_array.size() >= 2) { mPosition = LLVector3(path_array); // this construction handles LLSD without all components (values default to 0.f) if((F32(mPosition[VX]) < 0.f) || (mPosition[VX] > REGION_WIDTH_METERS) || (F32(mPosition[VY]) < 0.f) || (mPosition[VY] > REGION_WIDTH_METERS) || (F32(mPosition[VZ]) < 0.f) || (mPosition[VZ] > REGION_HEIGHT_METERS)) { mType = INVALID; return; } } else { // if x, y and z were not fully passed in, go to the middle of the region. // teleport will adjust the actual location to make sure you're on the ground // and such mPosition = LLVector3(REGION_WIDTH_METERS/2, REGION_WIDTH_METERS/2, 0); } } } }
bool LLAudioEngine_FMOD::init(const S32 num_channels, void* userdata) { mFadeIn = -10000; LLAudioEngine::init(num_channels, userdata); // Reserve one extra channel for the http stream. if (!FSOUND_SetMinHardwareChannels(num_channels + 1)) { LL_WARNS("AppInit") << "FMOD::init[0](), error: " << FMOD_ErrorString(FSOUND_GetError()) << LL_ENDL; } LL_DEBUGS("AppInit") << "LLAudioEngine_FMOD::init() initializing FMOD" << LL_ENDL; F32 version = FSOUND_GetVersion(); if (version < FMOD_VERSION) { LL_WARNS("AppInit") << "Error : You are using the wrong FMOD version (" << version << ")! You should be using FMOD " << FMOD_VERSION << LL_ENDL; //return false; } U32 fmod_flags = 0x0; #if LL_WINDOWS // Windows needs to know which window is frontmost. // This must be called before FSOUND_Init() per the FMOD docs. // This could be used to let FMOD handle muting when we lose focus, // but we don't actually want to do that because we want to distinguish // between minimized and not-focused states. if (!FSOUND_SetHWND(userdata)) { LL_WARNS("AppInit") << "Error setting FMOD window: " << FMOD_ErrorString(FSOUND_GetError()) << LL_ENDL; return false; } // Play audio when we don't have focus. // (For example, IM client on top of us.) // This means we also try to play audio when minimized, // so we manually handle muting in that case. JC fmod_flags |= FSOUND_INIT_GLOBALFOCUS; #endif #if LL_LINUX // initialize the FMOD engine // This is a hack to use only FMOD's basic FPU mixer // when the LL_VALGRIND environmental variable is set, // otherwise valgrind will fall over on FMOD's MMX detection if (getenv("LL_VALGRIND")) /*Flawfinder: ignore*/ { LL_INFOS("AppInit") << "Pacifying valgrind in FMOD init." << LL_ENDL; FSOUND_SetMixer(FSOUND_MIXER_QUALITY_FPU); } // If we don't set an output method, Linux FMOD always // decides on OSS and fails otherwise. So we'll manually // try ESD, then OSS, then ALSA. // Why this order? See SL-13250, but in short, OSS emulated // on top of ALSA is ironically more reliable than raw ALSA. // Ack, and ESD has more reliable failure modes - but has worse // latency - than all of them, so wins for now. bool audio_ok = false; if (!audio_ok) if (NULL == getenv("LL_BAD_FMOD_ESD")) /*Flawfinder: ignore*/ { LL_DEBUGS("AppInit") << "Trying ESD audio output..." << LL_ENDL; if(FSOUND_SetOutput(FSOUND_OUTPUT_ESD) && FSOUND_Init(44100, num_channels, fmod_flags)) { LL_DEBUGS("AppInit") << "ESD audio output initialized OKAY" << LL_ENDL; audio_ok = true; } else { LL_WARNS("AppInit") << "ESD audio output FAILED to initialize: " << FMOD_ErrorString(FSOUND_GetError()) << LL_ENDL; } } else { LL_DEBUGS("AppInit") << "ESD audio output SKIPPED" << LL_ENDL; } if (!audio_ok) if (NULL == getenv("LL_BAD_FMOD_OSS")) /*Flawfinder: ignore*/ { LL_DEBUGS("AppInit") << "Trying OSS audio output..." << LL_ENDL; if(FSOUND_SetOutput(FSOUND_OUTPUT_OSS) && FSOUND_Init(44100, num_channels, fmod_flags)) { LL_DEBUGS("AppInit") << "OSS audio output initialized OKAY" << LL_ENDL; audio_ok = true; } else { LL_WARNS("AppInit") << "OSS audio output FAILED to initialize: " << FMOD_ErrorString(FSOUND_GetError()) << LL_ENDL; } } else { LL_DEBUGS("AppInit") << "OSS audio output SKIPPED" << LL_ENDL; } if (!audio_ok) if (NULL == getenv("LL_BAD_FMOD_ALSA")) /*Flawfinder: ignore*/ { LL_DEBUGS("AppInit") << "Trying ALSA audio output..." << LL_ENDL; if(FSOUND_SetOutput(FSOUND_OUTPUT_ALSA) && FSOUND_Init(44100, num_channels, fmod_flags)) { LL_DEBUGS("AppInit") << "ALSA audio output initialized OKAY" << LL_ENDL; audio_ok = true; } else { LL_WARNS("AppInit") << "ALSA audio output FAILED to initialize: " << FMOD_ErrorString(FSOUND_GetError()) << LL_ENDL; } } else { LL_DEBUGS("AppInit") << "OSS audio output SKIPPED" << LL_ENDL; } if (!audio_ok) { LL_WARNS("AppInit") << "Overall audio init failure." << LL_ENDL; return false; } // On Linux, FMOD causes a SIGPIPE for some netstream error // conditions (an FMOD bug); ignore SIGPIPE so it doesn't crash us. // NOW FIXED in FMOD 3.x since 2006-10-01. //signal(SIGPIPE, SIG_IGN); // We're interested in logging which output method we // ended up with, for QA purposes. switch (FSOUND_GetOutput()) { case FSOUND_OUTPUT_NOSOUND: LL_DEBUGS("AppInit") << "Audio output: NoSound" << LL_ENDL; break; case FSOUND_OUTPUT_OSS: LL_DEBUGS("AppInit") << "Audio output: OSS" << LL_ENDL; break; case FSOUND_OUTPUT_ESD: LL_DEBUGS("AppInit") << "Audio output: ESD" << LL_ENDL; break; case FSOUND_OUTPUT_ALSA: LL_DEBUGS("AppInit") << "Audio output: ALSA" << LL_ENDL; break; default: LL_INFOS("AppInit") << "Audio output: Unknown!" << LL_ENDL; break; }; #else // LL_LINUX // initialize the FMOD engine if (!FSOUND_Init(44100, num_channels, fmod_flags)) { LL_WARNS("AppInit") << "Error initializing FMOD: " << FMOD_ErrorString(FSOUND_GetError()) << LL_ENDL; return false; } #endif initInternetStream(); LL_DEBUGS("AppInit") << "LLAudioEngine_FMOD::init() FMOD initialized correctly" << LL_ENDL; mInited = true; return true; }
LLDir_Win32::LLDir_Win32() { mDirDelimiter = "\\"; WCHAR w_str[MAX_PATH]; // Application Data is where user settings go SHGetSpecialFolderPath(NULL, w_str, CSIDL_APPDATA, TRUE); mOSUserDir = utf16str_to_utf8str(llutf16string(w_str)); // We want cache files to go on the local disk, even if the // user is on a network with a "roaming profile". // // On XP this is: // C:\Docments and Settings\James\Local Settings\Application Data // On Vista this is: // C:\Users\James\AppData\Local // // We used to store the cache in AppData\Roaming, and the installer // cleans up that version on upgrade. JC SHGetSpecialFolderPath(NULL, w_str, CSIDL_LOCAL_APPDATA, TRUE); mOSCacheDir = utf16str_to_utf8str(llutf16string(w_str)); if (GetTempPath(MAX_PATH, w_str)) { if (wcslen(w_str)) /* Flawfinder: ignore */ { w_str[wcslen(w_str)-1] = '\0'; /* Flawfinder: ignore */ // remove trailing slash } mTempDir = utf16str_to_utf8str(llutf16string(w_str)); } else { mTempDir = mOSUserDir; } // fprintf(stderr, "mTempDir = <%s>",mTempDir); #if 1 // Don't use the real app path for now, as we'll have to add parsing to detect if // we're in a developer tree, which has a different structure from the installed product. S32 size = GetModuleFileName(NULL, w_str, MAX_PATH); if (size) { w_str[size] = '\0'; mExecutablePathAndName = utf16str_to_utf8str(llutf16string(w_str)); S32 path_end = mExecutablePathAndName.find_last_of('\\'); if (path_end != std::string::npos) { mExecutableDir = mExecutablePathAndName.substr(0, path_end); mExecutableFilename = mExecutablePathAndName.substr(path_end+1, std::string::npos); } else { mExecutableFilename = mExecutablePathAndName; } GetCurrentDirectory(MAX_PATH, w_str); mWorkingDir = utf16str_to_utf8str(llutf16string(w_str)); } else { LL_WARNS("AppInit") << "Couldn't get APP path, assuming current directory!\n" << LL_ENDL; GetCurrentDirectory(MAX_PATH, w_str); mExecutableDir = utf16str_to_utf8str(llutf16string(w_str)); // Assume it's the current directory } #else GetCurrentDirectory(MAX_PATH, w_str); mExecutableDir = utf16str_to_utf8str(llutf16string(w_str)); #endif // When running in a dev tree, app_settings is under indra/newview/ // but in production it is under Program Files/SecondLife/ // Attempt to detect which one we're using. JC if (mExecutableDir.find("indra") != std::string::npos) mAppRODataDir = getCurPath(); else mAppRODataDir = mExecutableDir; // Build the default cache directory mDefaultCacheDir = buildSLOSCacheDir(); // Make sure it exists int res = LLFile::mkdir(mDefaultCacheDir); if (res == -1) { if (errno != EEXIST) { llwarns << "Couldn't create LL_PATH_CACHE dir " << mDefaultCacheDir << llendl; } } mLLPluginDir = mExecutableDir + mDirDelimiter + "llplugin"; }
//static void LLObjectBackup::exportWorker(void *userdata) { LLObjectBackup* self = findInstance(); if (!self) { gIdleCallbacks.deleteFunction(exportWorker); LL_WARNS() << "Export process aborted. LLObjectBackup instance gone !" << LL_ENDL; LLNotifications::instance().add("ExportAborted"); return; } self->updateExportNumbers(); switch (self->mExportState) { case EXPORT_INIT: { self->showFloater(true); //LLSelectMgr::getInstance()->getSelection()->ref(); // Singu Note: Don't do this. // Fall through to EXPORT_CHECK_PERMS } case EXPORT_CHECK_PERMS: { struct ff : public LLSelectedNodeFunctor { virtual bool apply(LLSelectNode* node) { return LLObjectBackup::validateNode(node); } } func; LLViewerObject* object; object = LLSelectMgr::getInstance()->getSelection()->getPrimaryObject(); if (object) { if (LLSelectMgr::getInstance()->getSelection()->applyToNodes(&func, false)) { self->mExportState = EXPORT_FETCH_PHYSICS; } else { struct vv : public LLSelectedNodeFunctor { virtual bool apply(LLSelectNode* node) { return node->mValid; } } func2; if (LLSelectMgr::getInstance()->getSelection()->applyToNodes(&func2, false)) { LL_WARNS() << "Incorrect permission to export" << LL_ENDL; self->mExportState = EXPORT_FAILED; LLSelectMgr::getInstance()->getSelection()->unref(); } else { LL_DEBUGS("ObjectBackup") << "Nodes permissions not yet received, delaying..." << LL_ENDL; self->mExportState = EXPORT_CHECK_PERMS; } } } else { self->mExportState = EXPORT_ABORTED; LLSelectMgr::getInstance()->getSelection()->unref(); } break; } case EXPORT_FETCH_PHYSICS: { // Don't bother to try and fetch the extra physics flags if we // don't have sim support for them... if (!self->mGotExtraPhysics) { self->mExportState = EXPORT_STRUCTURE; break; } struct ff : public LLSelectedNodeFunctor { virtual bool apply(LLSelectNode* node) { LLViewerObject* object = node->getObject(); return gObjectList.gotObjectPhysicsFlags(object); } } func; LLViewerObject* object = LLSelectMgr::getInstance()->getSelection()->getPrimaryObject(); if (object) { if (LLSelectMgr::getInstance()->getSelection()->applyToNodes(&func, false)) { self->mExportState = EXPORT_STRUCTURE; } else { LL_DEBUGS("ObjectBackup") << "Nodes physics not yet received, delaying..." << LL_ENDL; } } else { self->mExportState = EXPORT_ABORTED; LLSelectMgr::getInstance()->getSelection()->unref(); } break; } case EXPORT_STRUCTURE: { struct ff : public LLSelectedObjectFunctor { virtual bool apply(LLViewerObject* object) { bool is_attachment = object->isAttachment(); object->boostTexturePriority(true); LLViewerObject::child_list_t children = object->getChildren(); children.push_front(object); //push root onto list LLObjectBackup* self = findInstance(); LLSD prim_llsd = self->primsToLLSD(children, is_attachment); LLSD stuff; if (is_attachment) { stuff["root_position"] = object->getPositionEdit().getValue(); stuff["root_rotation"] = ll_sd_from_quaternion(object->getRotationEdit()); } else { stuff["root_position"] = object->getPosition().getValue(); stuff["root_rotation"] = ll_sd_from_quaternion(object->getRotation()); } stuff["group_body"] = prim_llsd; self->mLLSD["data"].append(stuff); return true; } } func; LLViewerObject* object; object = LLSelectMgr::getInstance()->getSelection()->getPrimaryObject(); if (object) { self->mExportState = EXPORT_LLSD; LLSelectMgr::getInstance()->getSelection()->applyToRootObjects(&func, false); } else { self->mExportState = EXPORT_ABORTED; } LLSelectMgr::getInstance()->getSelection()->unref(); break; } case EXPORT_TEXTURES: { if (!self->mCheckNextTexture) { // The texture is being fetched. Wait till next idle callback. return; } if (self->mTexturesList.empty()) { self->mExportState = EXPORT_DONE; return; } // Ok, we got work to do... self->mCheckNextTexture = false; self->exportNextTexture(); break; } case EXPORT_LLSD: { // Create a file stream and write to it llofstream export_file(self->mFileName); LLSDSerialize::toPrettyXML(self->mLLSD, export_file); export_file.close(); self->mCheckNextTexture = true; self->mExportState = EXPORT_TEXTURES; break; } case EXPORT_DONE: { gIdleCallbacks.deleteFunction(exportWorker); if (self->mNonExportedTextures == LLObjectBackup::TEXTURE_OK) { LL_INFOS() << "Export successful and complete." << LL_ENDL; LLNotificationsUtil::add("ExportSuccessful"); } else { LL_INFOS() << "Export successful but incomplete: some texture(s) not saved." << LL_ENDL; std::string reason; U32 error_bits_map = self->mNonExportedTextures; if (error_bits_map & LLObjectBackup::TEXTURE_BAD_PERM) { reason += "\nBad permissions/creator."; } if (error_bits_map & LLObjectBackup::TEXTURE_MISSING) { reason += "\nMissing texture (retrying after full rezzing might work)."; } if (error_bits_map & LLObjectBackup::TEXTURE_BAD_ENCODING) { reason += "\nBad texture encoding."; } if (error_bits_map & LLObjectBackup::TEXTURE_IS_NULL) { reason += "\nNull texture."; } if (error_bits_map & LLObjectBackup::TEXTURE_SAVED_FAILED) { reason += "\nCould not write to disk."; } LLSD args; args["REASON"] = reason; LLNotificationsUtil::add("ExportPartial", args); } self->destroy(); break; } case EXPORT_FAILED: { gIdleCallbacks.deleteFunction(exportWorker); LL_WARNS() << "Export process failed." << LL_ENDL; LLNotificationsUtil::add("ExportFailed"); self->destroy(); break; } case EXPORT_ABORTED: { gIdleCallbacks.deleteFunction(exportWorker); LL_WARNS() << "Export process aborted." << LL_ENDL; LLNotificationsUtil::add("ExportAborted"); self->destroy(); break; } } }
///////////////////////////////////////////////////////////////////////////////////////// // inherited from LLViewerMediaObserver // virtual void LLViewerParcelMedia::handleMediaEvent(LLPluginClassMedia* self, EMediaEvent event) { switch(event) { case MEDIA_EVENT_DEBUG_MESSAGE: { // LL_DEBUGS("Media") << "Media event: MEDIA_EVENT_DEBUG_MESSAGE " << LL_ENDL; }; break; case MEDIA_EVENT_CONTENT_UPDATED: { // LL_DEBUGS("Media") << "Media event: MEDIA_EVENT_CONTENT_UPDATED " << LL_ENDL; }; break; case MEDIA_EVENT_TIME_DURATION_UPDATED: { // LL_DEBUGS("Media") << "Media event: MEDIA_EVENT_TIME_DURATION_UPDATED, time is " << self->getCurrentTime() << " of " << self->getDuration() << LL_ENDL; }; break; case MEDIA_EVENT_SIZE_CHANGED: { LL_DEBUGS("Media") << "Media event: MEDIA_EVENT_SIZE_CHANGED " << LL_ENDL; }; break; case MEDIA_EVENT_CURSOR_CHANGED: { LL_DEBUGS("Media") << "Media event: MEDIA_EVENT_CURSOR_CHANGED, new cursor is " << self->getCursorName() << LL_ENDL; }; break; case MEDIA_EVENT_NAVIGATE_BEGIN: { LL_DEBUGS("Media") << "Media event: MEDIA_EVENT_NAVIGATE_BEGIN " << LL_ENDL; }; break; case MEDIA_EVENT_NAVIGATE_COMPLETE: { LL_DEBUGS("Media") << "Media event: MEDIA_EVENT_NAVIGATE_COMPLETE, result string is: " << self->getNavigateResultString() << LL_ENDL; }; break; case MEDIA_EVENT_PROGRESS_UPDATED: { LL_DEBUGS("Media") << "Media event: MEDIA_EVENT_PROGRESS_UPDATED, loading at " << self->getProgressPercent() << "%" << LL_ENDL; }; break; case MEDIA_EVENT_STATUS_TEXT_CHANGED: { LL_DEBUGS("Media") << "Media event: MEDIA_EVENT_STATUS_TEXT_CHANGED, new status text is: " << self->getStatusText() << LL_ENDL; }; break; case MEDIA_EVENT_LOCATION_CHANGED: { LL_DEBUGS("Media") << "Media event: MEDIA_EVENT_LOCATION_CHANGED, new uri is: " << self->getLocation() << LL_ENDL; }; break; case MEDIA_EVENT_NAVIGATE_ERROR_PAGE: { LL_DEBUGS("Media") << "Media event: MEDIA_EVENT_NAVIGATE_ERROR_PAGE" << LL_ENDL; }; break; case MEDIA_EVENT_CLICK_LINK_HREF: { LL_DEBUGS("Media") << "Media event: MEDIA_EVENT_CLICK_LINK_HREF, target is \"" << self->getClickTarget() << "\", uri is " << self->getClickURL() << LL_ENDL; }; break; case MEDIA_EVENT_CLICK_LINK_NOFOLLOW: { LL_DEBUGS("Media") << "Media event: MEDIA_EVENT_CLICK_LINK_NOFOLLOW, uri is " << self->getClickURL() << LL_ENDL; }; break; case MEDIA_EVENT_PLUGIN_FAILED: { LL_DEBUGS("Media") << "Media event: MEDIA_EVENT_PLUGIN_FAILED" << LL_ENDL; }; break; case MEDIA_EVENT_PLUGIN_FAILED_LAUNCH: { LL_DEBUGS("Media") << "Media event: MEDIA_EVENT_PLUGIN_FAILED_LAUNCH" << LL_ENDL; }; break; case MEDIA_EVENT_NAME_CHANGED: { LL_DEBUGS("Media") << "Media event: MEDIA_EVENT_NAME_CHANGED" << LL_ENDL; }; break; case MEDIA_EVENT_CLOSE_REQUEST: { LL_DEBUGS("Media") << "Media event: MEDIA_EVENT_CLOSE_REQUEST" << LL_ENDL; } break; case MEDIA_EVENT_PICK_FILE_REQUEST: { LL_DEBUGS("Media") << "Media event: MEDIA_EVENT_PICK_FILE_REQUEST" << LL_ENDL; } break; case MEDIA_EVENT_GEOMETRY_CHANGE: { LL_DEBUGS("Media") << "Media event: MEDIA_EVENT_GEOMETRY_CHANGE, uuid is " << self->getClickUUID() << LL_ENDL; } break; case MEDIA_EVENT_AUTH_REQUEST: { LL_DEBUGS("Media") << "Media event: MEDIA_EVENT_AUTH_REQUEST, url " << self->getAuthURL() << ", realm " << self->getAuthRealm() << LL_ENDL; } break; case MEDIA_EVENT_LINK_HOVERED: { LL_DEBUGS("Media") << "Media event: MEDIA_EVENT_LINK_HOVERED, hover text is: " << self->getHoverText() << LL_ENDL; }; break; default: { LL_WARNS("Media") << "Media event: unknown event type" << LL_ENDL; } }; }
//virtual virtual void uploadComplete(const LLSD& content) { LLObjectBackup* self = LLObjectBackup::findInstance(); if (!self) { LL_WARNS() << "Import aborted, LLObjectBackup instance gone !" << LL_ENDL; // remove the "Uploading..." message LLUploadDialog::modalUploadFinished(); return; } LLAssetType::EType asset_type = LLAssetType::lookup(mPostData["asset_type"].asString()); LLInventoryType::EType inv_type = LLInventoryType::lookup(mPostData["inventory_type"].asString()); // Update L$ and ownership credit information // since it probably changed on the server if (asset_type == LLAssetType::AT_TEXTURE || asset_type == LLAssetType::AT_SOUND || asset_type == LLAssetType::AT_ANIMATION) { LLMessageSystem* msg = gMessageSystem; msg->newMessageFast(_PREHASH_MoneyBalanceRequest); msg->nextBlockFast(_PREHASH_AgentData); msg->addUUIDFast(_PREHASH_AgentID, gAgentID); msg->addUUIDFast(_PREHASH_SessionID, gAgentSessionID); msg->nextBlockFast(_PREHASH_MoneyData); msg->addUUIDFast(_PREHASH_TransactionID, LLUUID::null); gAgent.sendReliableMessage(); } // Actually add the upload to viewer inventory LL_INFOS() << "Adding " << content["new_inventory_item"].asUUID() << " " << content["new_asset"].asUUID() << " to inventory." << LL_ENDL; if (mPostData["folder_id"].asUUID().notNull()) { LLPermissions perm; U32 next_owner_perm; perm.init(gAgentID, gAgentID, LLUUID::null, LLUUID::null); if (mPostData["inventory_type"].asString() == "snapshot") { next_owner_perm = PERM_ALL; } else { next_owner_perm = PERM_MOVE | PERM_TRANSFER; } perm.initMasks(PERM_ALL, PERM_ALL, PERM_NONE, PERM_NONE, next_owner_perm); S32 creation_date_now = time_corrected(); LLPointer<LLViewerInventoryItem> item; item = new LLViewerInventoryItem(content["new_inventory_item"].asUUID(), mPostData["folder_id"].asUUID(), perm, content["new_asset"].asUUID(), asset_type, inv_type, mPostData["name"].asString(), mPostData["description"].asString(), LLSaleInfo::DEFAULT, LLInventoryItemFlags::II_FLAGS_NONE, creation_date_now); gInventory.updateItem(item); gInventory.notifyObservers(); } else { LL_WARNS() << "Can't find a folder to put it into" << LL_ENDL; } // remove the "Uploading..." message LLUploadDialog::modalUploadFinished(); self->updateMap(content["new_asset"].asUUID()); self->uploadNextAsset(); }
void LLDrawable::updateDistance(LLCamera& camera, bool force_update) { if (LLViewerCamera::sCurCameraID != LLViewerCamera::CAMERA_WORLD) { LL_WARNS() << "Attempted to update distance for non-world camera." << LL_ENDL; return; } if (gShiftFrame) { return; } //switch LOD with the spatial group to avoid artifacts //LLSpatialGroup* sg = getSpatialGroup(); LLVector3 pos; //if (!sg || sg->changeLOD()) { LLVOVolume* volume = getVOVolume(); if (volume) { if (getGroup()) { pos.set(getPositionGroup().getF32ptr()); } else { pos = getPositionAgent(); } if (isState(LLDrawable::HAS_ALPHA)) { for (S32 i = 0; i < getNumFaces(); i++) { LLFace* facep = getFace(i); if (facep && (force_update || facep->getPoolType() == LLDrawPool::POOL_ALPHA)) { LLVector4a box; box.setSub(facep->mExtents[1], facep->mExtents[0]); box.mul(0.25f); LLVector3 v = (facep->mCenterLocal-camera.getOrigin()); const LLVector3& at = camera.getAtAxis(); for (U32 j = 0; j < 3; j++) { v.mV[j] -= box[j] * at.mV[j]; } facep->mDistance = v * camera.getAtAxis(); } } } } else { pos = LLVector3(getPositionGroup().getF32ptr()); } pos -= camera.getOrigin(); mDistanceWRTCamera = ll_round(pos.magVec(), 0.01f); mVObjp->updateLOD(); } }
//////////////////////////////////////////////////////////////////////////////// // inherited from LLViewerMediaObserver //virtual void LLMediaCtrl::handleMediaEvent(LLPluginClassMedia* self, EMediaEvent event) { switch(event) { case MEDIA_EVENT_CONTENT_UPDATED: { // LL_DEBUGS("Media") << "Media event: MEDIA_EVENT_CONTENT_UPDATED " << LL_ENDL; }; break; case MEDIA_EVENT_TIME_DURATION_UPDATED: { // LL_DEBUGS("Media") << "Media event: MEDIA_EVENT_TIME_DURATION_UPDATED, time is " << self->getCurrentTime() << " of " << self->getDuration() << LL_ENDL; }; break; case MEDIA_EVENT_SIZE_CHANGED: { LL_DEBUGS("Media") << "Media event: MEDIA_EVENT_SIZE_CHANGED " << LL_ENDL; LLRect r = getRect(); reshape( r.getWidth(), r.getHeight(), FALSE ); }; break; case MEDIA_EVENT_CURSOR_CHANGED: { LL_DEBUGS("Media") << "Media event: MEDIA_EVENT_CURSOR_CHANGED, new cursor is " << self->getCursorName() << LL_ENDL; } break; case MEDIA_EVENT_NAVIGATE_BEGIN: { LL_DEBUGS("Media") << "Media event: MEDIA_EVENT_NAVIGATE_BEGIN, url is " << self->getNavigateURI() << LL_ENDL; hideNotification(); }; break; case MEDIA_EVENT_NAVIGATE_COMPLETE: { LL_DEBUGS("Media") << "Media event: MEDIA_EVENT_NAVIGATE_COMPLETE, result string is: " << self->getNavigateResultString() << LL_ENDL; if(mHidingInitialLoad) { mHidingInitialLoad = false; } }; break; case MEDIA_EVENT_PROGRESS_UPDATED: { LL_DEBUGS("Media") << "Media event: MEDIA_EVENT_PROGRESS_UPDATED, loading at " << self->getProgressPercent() << "%" << LL_ENDL; }; break; case MEDIA_EVENT_STATUS_TEXT_CHANGED: { LL_DEBUGS("Media") << "Media event: MEDIA_EVENT_STATUS_TEXT_CHANGED, new status text is: " << self->getStatusText() << LL_ENDL; }; break; case MEDIA_EVENT_LOCATION_CHANGED: { LL_DEBUGS("Media") << "Media event: MEDIA_EVENT_LOCATION_CHANGED, new uri is: " << self->getLocation() << LL_ENDL; mCurrentNavUrl = self->getLocation(); }; break; case MEDIA_EVENT_NAVIGATE_ERROR_PAGE: { LL_DEBUGS("Media") << "Media event: MEDIA_EVENT_NAVIGATE_ERROR_PAGE" << LL_ENDL; if ( mErrorPageURL.length() > 0 ) { navigateTo(mErrorPageURL, "text/html"); }; }; break; case MEDIA_EVENT_CLICK_LINK_HREF: { LL_DEBUGS("Media") << "Media event: MEDIA_EVENT_CLICK_LINK_HREF, target is \"" << self->getClickTarget() << "\", uri is " << self->getClickURL() << LL_ENDL; // retrieve the event parameters std::string url = self->getClickURL(); std::string target = self->getClickTarget(); std::string uuid = self->getClickUUID(); LLWeb::loadURL(url, target, std::string()); //LLNotification::Params notify_params("PopupAttempt"); //notify_params.payload = LLSD().with("target", target).with("url", url).with("uuid", uuid).with("media_id", mMediaTextureID); //notify_params.functor(boost::bind(&LLMediaCtrl::onPopup, this, _1, _2)); //if (mTrusted) //{ // LLNotifications::instance().forceResponse(notify_params, 0); //} //else //{ // LLNotifications::instance().add(notify_params); //} break; }; case MEDIA_EVENT_CLICK_LINK_NOFOLLOW: { LL_DEBUGS("Media") << "Media event: MEDIA_EVENT_CLICK_LINK_NOFOLLOW, uri is " << self->getClickURL() << LL_ENDL; }; break; case MEDIA_EVENT_PLUGIN_FAILED: { LL_DEBUGS("Media") << "Media event: MEDIA_EVENT_PLUGIN_FAILED" << LL_ENDL; }; break; case MEDIA_EVENT_PLUGIN_FAILED_LAUNCH: { LL_DEBUGS("Media") << "Media event: MEDIA_EVENT_PLUGIN_FAILED_LAUNCH" << LL_ENDL; }; break; case MEDIA_EVENT_NAME_CHANGED: { LL_DEBUGS("Media") << "Media event: MEDIA_EVENT_NAME_CHANGED" << LL_ENDL; }; break; case MEDIA_EVENT_CLOSE_REQUEST: { LL_DEBUGS("Media") << "Media event: MEDIA_EVENT_CLOSE_REQUEST" << LL_ENDL; } break; case MEDIA_EVENT_PICK_FILE_REQUEST: { LL_DEBUGS("Media") << "Media event: MEDIA_EVENT_PICK_FILE_REQUEST" << LL_ENDL; } break; case MEDIA_EVENT_GEOMETRY_CHANGE: { LL_DEBUGS("Media") << "Media event: MEDIA_EVENT_GEOMETRY_CHANGE, uuid is " << self->getClickUUID() << LL_ENDL; } break; case MEDIA_EVENT_AUTH_REQUEST: { LLNotification::Params auth_request_params("AuthRequest"); // pass in host name and realm for site (may be zero length but will always exist) LLSD args; LLURL raw_url( self->getAuthURL().c_str() ); args["HOST_NAME"] = raw_url.getAuthority(); args["REALM"] = self->getAuthRealm(); auth_request_params.substitutions = args; auth_request_params.payload = LLSD().with("media_id", mMediaTextureID); auth_request_params.functor(boost::bind(&LLViewerMedia::onAuthSubmit, _1, _2)); LLNotifications::instance().add(auth_request_params); }; break; case MEDIA_EVENT_LINK_HOVERED: { LL_DEBUGS("Media") << "Media event: MEDIA_EVENT_LINK_HOVERED, hover text is: " << self->getHoverText() << LL_ENDL; mHoverTextChanged = true; }; break; case MEDIA_EVENT_FILE_DOWNLOAD: { //llinfos << "Media event - file download requested - filename is " << self->getFileDownloadFilename() << llendl; //LLNotificationsUtil::add("MediaFileDownloadUnsupported"); }; break; case MEDIA_EVENT_DEBUG_MESSAGE: { LL_INFOS("media") << self->getDebugMessageText() << LL_ENDL; }; break; default: { LL_WARNS("Media") << "Media event: unknown event type" << LL_ENDL; }; }; // chain all events to any potential observers of this object. emitEvent(self, event); }
BOOL LLFeatureManager::loadFeatureTables() { // *TODO - if I or anyone else adds something else to the skipped list // make this data driven. Put it in the feature table and parse it // correctly mSkippedFeatures.insert("RenderAnisotropic"); mSkippedFeatures.insert("RenderGamma"); mSkippedFeatures.insert("RenderVBOEnable"); mSkippedFeatures.insert("RenderFogRatio"); std::string data_path = gDirUtilp->getAppRODataDir(); data_path += gDirUtilp->getDirDelimiter(); data_path += FEATURE_TABLE_FILENAME; lldebugs << "Looking for feature table in " << data_path << llendl; llifstream file; std::string name; U32 version; file.open(data_path); /*Flawfinder: ignore*/ if (!file) { LL_WARNS("RenderInit") << "Unable to open feature table!" << LL_ENDL; return FALSE; } // Check file version file >> name; file >> version; if (name != "version") { LL_WARNS("RenderInit") << data_path << " does not appear to be a valid feature table!" << LL_ENDL; return FALSE; } mTableVersion = version; LLFeatureList *flp = NULL; while (!file.eof() && file.good()) { char buffer[MAX_STRING]; /*Flawfinder: ignore*/ file >> name; if (name.substr(0,2) == "//") { // This is a comment. file.getline(buffer, MAX_STRING); continue; } if (name.empty()) { // This is a blank line file.getline(buffer, MAX_STRING); continue; } if (name == "list") { if (flp) { //flp->dump(); } // It's a new mask, create it. file >> name; if (mMaskList.count(name)) { LL_ERRS("RenderInit") << "Overriding mask " << name << ", this is invalid!" << LL_ENDL; } flp = new LLFeatureList(name); mMaskList[name] = flp; } else { if (!flp) { LL_ERRS("RenderInit") << "Specified parameter before <list> keyword!" << LL_ENDL; } S32 available; F32 recommended; file >> available >> recommended; flp->addFeature(name, available, recommended); } }