Example #1
0
String& String::operator+(String& str)
{
	String* s = new String();
	s->SetLength(this->GetLength() + str.GetLength());
	s->Alloc(s->GetLength());
	char* p = s->mBuffer;
	strncpy(p,this->string(), this->GetLength());
	strncpy(p+this->GetLength(), str.string(), str.GetLength());
	
	return *s;
}
Example #2
0
void NoiseGateSettings::ApplySettings()
{
    String str;
    int val;
    HWND ctrlHwnd;

    // Gate enabled
    if(SendMessage(GetDlgItem(hwnd, IDC_ENABLEGATE), BM_GETCHECK, 0, 0) == BST_CHECKED)
        parent->isEnabled = true;
    else
        parent->isEnabled = false;

    // Attack time
    ctrlHwnd = GetDlgItem(hwnd, IDC_ATTACKTIME_EDIT);
    str.SetLength(GetWindowTextLength(ctrlHwnd));
    GetWindowText(ctrlHwnd, str, str.Length() + 1);
    parent->attackTime = (float)str.ToInt() * 0.001f;

    // Hold time
    ctrlHwnd = GetDlgItem(hwnd, IDC_HOLDTIME_EDIT);
    str.SetLength(GetWindowTextLength(ctrlHwnd));
    GetWindowText(ctrlHwnd, str, str.Length() + 1);
    parent->holdTime = (float)str.ToInt() * 0.001f;

    // Release time
    ctrlHwnd = GetDlgItem(hwnd, IDC_RELEASETIME_EDIT);
    str.SetLength(GetWindowTextLength(ctrlHwnd));
    GetWindowText(ctrlHwnd, str, str.Length() + 1);
    parent->releaseTime = (float)str.ToInt() * 0.001f;

    // Close threshold
    val = (int)SendMessage(GetDlgItem(hwnd, IDC_CLOSETHRES_SLIDER), TBM_GETPOS, 0, 0);
    parent->closeThreshold = dbToRms((float)(-val));

    // Open threshold
    val = (int)SendMessage(GetDlgItem(hwnd, IDC_OPENTHRES_SLIDER), TBM_GETPOS, 0, 0);
    parent->openThreshold = dbToRms((float)(-val));

    // Save to file
    parent->SaveSettings();
}
Example #3
0
String XConfig::ProcessString(TSTR &lpTemp)
{
    TSTR lpStart = lpTemp;

    BOOL bFoundEnd = FALSE;
    while(*++lpTemp)
    {
        if(*lpTemp == '"' && lpTemp[-1] != '\\')
        {
            bFoundEnd = TRUE;
            break;
        }
    }

    if(!bFoundEnd)
        return String();

    ++lpTemp;

    TCHAR backupChar = *lpTemp;
    *lpTemp = 0;
    String string = lpStart;
    *lpTemp = backupChar;

    String stringOut = string.Mid(1, string.Length()-1);
    if(stringOut.IsEmpty())
        return String();

    TSTR lpStringOut = stringOut;
    while(*lpStringOut != 0 && (lpStringOut = schr(lpStringOut, '\\')) != 0)
    {
        switch(lpStringOut[1])
        {
            case 0:     *lpStringOut = 0; break;
            case '"':   *lpStringOut = '"';  scpy(lpStringOut+1, lpStringOut+2); break;
            case 't':   *lpStringOut = '\t'; scpy(lpStringOut+1, lpStringOut+2); break;
            case 'r':   *lpStringOut = '\r'; scpy(lpStringOut+1, lpStringOut+2); break;
            case 'n':   *lpStringOut = '\n'; scpy(lpStringOut+1, lpStringOut+2); break;
            case '/':   *lpStringOut = '/';  scpy(lpStringOut+1, lpStringOut+2); break;
            case '\\':  scpy(lpStringOut+1, lpStringOut+2); break;
        }

        lpStringOut++;
    }

    stringOut.SetLength(slen(stringOut));

    return stringOut;
}
Example #4
0
String FileFormat::Status() const
{
   size_type len = 0;
   (*API->FileFormat->GetFileFormatStatus)( m_data->handle, 0, &len, 0/*reserved*/ );

   String status;
   if ( len > 0 )
   {
      status.SetLength( len );
      if ( (*API->FileFormat->GetFileFormatStatus)( m_data->handle, status.Begin(), &len, 0/*reserved*/ ) == api_false )
         throw APIFunctionError( "GetFileFormatStatus" );
      status.ResizeToNullTerminated();
   }
   return status;
}
Example #5
0
String FileFormat::Implementation() const
{
   size_type len = 0;
   (*API->FileFormat->GetFileFormatImplementation)( m_data->handle, 0, &len );

   String implementation;
   if ( len > 0 )
   {
      implementation.SetLength( len );
      if ( (*API->FileFormat->GetFileFormatImplementation)( m_data->handle, implementation.Begin(), &len ) == api_false )
         throw APIFunctionError( "GetFileFormatImplementation" );
      implementation.ResizeToNullTerminated();
   }
   return implementation;
}
Example #6
0
String SpinBox::Suffix() const
{
   size_type len = 0;
   (*API->SpinBox->GetSpinBoxSuffix)( handle, 0, &len );

   String suffix;
   if ( len > 0 )
   {
      suffix.SetLength( len );
      if ( (*API->SpinBox->GetSpinBoxSuffix)( handle, suffix.Begin(), &len ) == api_false )
         throw APIFunctionError( "GetSpinBoxSuffix" );
      suffix.ResizeToNullTerminated();
   }
   return suffix;
}
Example #7
0
String Label::Text() const
{
   size_type len = 0;
   (*API->Label->GetLabelText)( handle, 0, &len );

   String text;
   if ( len > 0 )
   {
      text.SetLength( len );
      if ( (*API->Label->GetLabelText)( handle, text.Begin(), &len ) == api_false )
         throw APIFunctionError( "GetLabelText" );
      text.ResizeToNullTerminated();
   }
   return text;
}
Example #8
0
String SpinBox::MinimumValueText() const
{
   size_type len = 0;
   (*API->SpinBox->GetSpinBoxMinimumValueText)( handle, 0, &len );

   String text;
   if ( len > 0 )
   {
      text.SetLength( len );
      if ( (*API->SpinBox->GetSpinBoxMinimumValueText)( handle, text.Begin(), &len ) == api_false )
         throw APIFunctionError( "GetSpinBoxMinimumValueText" );
      text.ResizeToNullTerminated();
   }
   return text;
}
Example #9
0
String SVG::FilePath() const
{
   if ( !IsNull() )
   {
      size_type len = 0;
      (*API->SVG->GetSVGFilePath)( handle, 0, &len );
      if ( len > 0 )
      {
         String path;
         path.SetLength( len );
         if ( (*API->SVG->GetSVGFilePath)( handle, path.Begin(), &len ) == api_false )
            throw APIFunctionError( "GetSVGFilePath" );
         path.ResizeToNullTerminated();
         return path;
      }
   }

   return String();
}
Example #10
0
String SVG::Title() const
{
   if ( !IsNull() )
   {
      size_type len = 0;
      (*API->SVG->GetSVGTitle)( handle, 0, &len );
      if ( len > 0 )
      {
         String title;
         title.SetLength( len );
         if ( (*API->SVG->GetSVGTitle)( handle, title.Begin(), &len ) == api_false )
            throw APIFunctionError( "GetSVGTitle" );
         title.ResizeToNullTerminated();
         return title;
      }
   }

   return String();
}
Example #11
0
String SVG::Description() const
{
   if ( !IsNull() )
   {
      size_type len = 0;
      (*API->SVG->GetSVGDescription)( handle, 0, &len );
      if ( len > 0 )
      {
         String description;
         description.SetLength( len );
         if ( (*API->SVG->GetSVGDescription)( handle, description.Begin(), &len ) == api_false )
            throw APIFunctionError( "GetSVGDescription" );
         description.ResizeToNullTerminated();
         return description;
      }
   }

   return String();
}
String GetPathWithoutExtension(CTSTR lpPath)
{
    assert(lpPath);
    if(!lpPath)
        return String();

    TSTR lpExtensionStart = srchr(lpPath, '.');
    if(lpExtensionStart)
    {
        UINT newLength = (UINT)(UPARAM)(lpExtensionStart-lpPath);
        if(!newLength)
            return String();

        String newString;
        newString.SetLength(newLength);
        scpy_n(newString, lpPath, newLength);

        return newString;
    }
    else
        return String(lpPath);
}
String GetPathFileName(CTSTR lpPath, BOOL bExtension)
{
    assert(lpPath);
    if(!lpPath)
        return String();

    OSFindData ofd;
    HANDLE hFind = OSFindFirstFile(lpPath, ofd);

    if(!hFind)
        ofd.bDirectory = FALSE;
    else
        OSFindClose(hFind);

    if(!ofd.bDirectory)
    {
        CTSTR lpDirectoryEnd = srchr(lpPath, '/');

        if(!lpDirectoryEnd)
            lpDirectoryEnd = srchr(lpPath, '/');

        if(lpDirectoryEnd)
            lpPath = lpDirectoryEnd+1;
    }

    String newPath = lpPath;
    if(newPath.IsValid())
    {
        if(!bExtension)
        {
            TSTR pDot = srchr(newPath, '.');
            if(pDot)
                newPath.SetLength((int)((((UPARAM)pDot)-((UPARAM)newPath.Array()))/sizeof(TCHAR)));
        }
    }

    return newPath;
}
String GetPathDirectory(CTSTR lpPath)
{
    assert(lpPath);
    if(!lpPath)
        return String();

    OSFindData ofd;
    HANDLE hFind = OSFindFirstFile(lpPath, ofd);

    if(!hFind)
        ofd.bDirectory = FALSE;
    else
        OSFindClose(hFind);

    int nDirectoryEnd;

    if(!ofd.bDirectory)
    {
        CTSTR lpDirectoryEnd = srchr(lpPath, '/');

        if(!lpDirectoryEnd)
            lpDirectoryEnd = srchr(lpPath, '\\');

        if(lpDirectoryEnd)
            nDirectoryEnd = (int)((((UPARAM)lpDirectoryEnd)-((UPARAM)lpPath))/sizeof(TCHAR));
        else
            nDirectoryEnd = slen(lpPath);
    }
    else
        nDirectoryEnd = slen(lpPath);

    String newPath = lpPath;

    newPath.SetLength(nDirectoryEnd);
    return newPath;
}
Example #15
0
BOOL STDCALL OSFileHasChanged (OSFileChangeData *data)
{
    BOOL hasModified = FALSE;

    if (!data->hDirectory)
    {
        //we lost our directory handle for some reason, try to re-acquire it
        data->hDirectory = CreateFile(data->strDirectory, FILE_LIST_DIRECTORY, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS|FILE_FLAG_OVERLAPPED, NULL);
        if(data->hDirectory != INVALID_HANDLE_VALUE)
        {
            DWORD test;
            zero(&data->directoryChange, sizeof(data->directoryChange));

            data->directoryChange.hEvent = CreateEvent (NULL, TRUE, FALSE, NULL);

            if(ReadDirectoryChangesW(data->hDirectory, data->changeBuffer, 2048, FALSE, FILE_NOTIFY_CHANGE_FILE_NAME | FILE_NOTIFY_CHANGE_LAST_WRITE | FILE_NOTIFY_CHANGE_SIZE, &test, &data->directoryChange, NULL))
            {
            }
            else
            {
                int i = GetLastError ();
                CloseHandle(data->directoryChange.hEvent);
                CloseHandle(data->hDirectory);

                data->directoryChange.hEvent = NULL;
                data->hDirectory = NULL;

                return false;
            }
        }
    }

    if(HasOverlappedIoCompleted(&data->directoryChange))
    {
        FILE_NOTIFY_INFORMATION *notify = (FILE_NOTIFY_INFORMATION*)data->changeBuffer;

        //change triggered, process the notifications
        for (;;)
        {
            if (notify->Action == FILE_ACTION_ADDED || notify->Action == FILE_ACTION_MODIFIED || notify->Action == FILE_ACTION_RENAMED_NEW_NAME)
            {
                String strFileName;
                strFileName.SetLength(notify->FileNameLength);
                scpy_n(strFileName, notify->FileName, notify->FileNameLength/2);
                strFileName.KillSpaces();

                String strFileChanged;
                strFileChanged << data->strDirectory << strFileName;

                if(strFileChanged.CompareI(data->targetFileName))
                {
                    hasModified = TRUE;
                    break;
                }
            }

            if (!notify->NextEntryOffset)
                break;

            notify = (FILE_NOTIFY_INFORMATION*)((BYTE *)notify + notify->NextEntryOffset);
        }

        //prepare for next read
        ResetEvent (data->directoryChange.hEvent);
        zero(data->changeBuffer, sizeof(data->changeBuffer));

        DWORD test;
        if(ReadDirectoryChangesW(data->hDirectory, data->changeBuffer, 2048, FALSE, FILE_NOTIFY_CHANGE_FILE_NAME | FILE_NOTIFY_CHANGE_LAST_WRITE | FILE_NOTIFY_CHANGE_SIZE, &test, &data->directoryChange, NULL))
        {
        }
        else
        {
            int i = GetLastError ();
            CloseHandle(data->directoryChange.hEvent);
            CloseHandle(data->hDirectory);

            data->directoryChange.hEvent = NULL;
            data->hDirectory = NULL;

            return hasModified;
        }
    }

    return hasModified;
}
Example #16
0
void FTP::AddToQueque(FAR_FIND_DATA* FileName, LPCSTR Path, BOOL Download)
{
	String  str;
	char   *m;
	int     num;
	FTPUrl* p = new FTPUrl;
	memcpy(&p->Host, &Host, sizeof(Host));
	p->Download = Download;
	p->Next     = NULL;
	p->FileName = *FileName;
	p->Error.Null();
	p->DestPath = Path;

	if(Download)
		m = strrchr(FileName->cFileName, '/');
	else
		m = strrchr(FileName->cFileName, '\\');

	if(m)
	{
		*m = 0;
		p->DestPath.Add(m);
		memmove(FileName->cFileName, m+1, m-FileName->cFileName);
	}

	if(Download)
	{
		GetCurPath(p->SrcPath);
		AddEndSlash(p->SrcPath, '/');
		str.printf("%s%s", p->SrcPath.c_str(), FileName->cFileName);
		FixLocalSlash(p->DestPath);
		AddEndSlash(p->DestPath, '\\');
		num = str.Chr('/');
	}
	else
	{
		PanelInfo pi;
		FP_Info->Control(this, FCTL_GETANOTHERPANELINFO, &pi);
		p->SrcPath = pi.CurDir;
		AddEndSlash(p->SrcPath, '\\');
		str.printf("%s%s", p->SrcPath.c_str(), FileName->cFileName);
		FixLocalSlash(str);
		AddEndSlash(p->DestPath, '/');
		num = str.Chr('\\');
	}

	if(num != -1)
	{
		StrCpy(p->FileName.cFileName, str.c_str()+num+1, ARRAYSIZE(p->FileName.cFileName));
		str.SetLength(num);
		p->SrcPath = str;
	}
	else
	{
		StrCpy(p->FileName.cFileName, str.c_str(), ARRAYSIZE(p->FileName.cFileName));
		p->SrcPath.Null();
	}

	if(!UrlsList) UrlsList = p;

	if(UrlsTail)  UrlsTail->Next = p;

	UrlsTail = p;
	QuequeSize++;
}
Example #17
0
LRESULT WINAPI ObjectBrowserProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    traceIn(ObjectBrowserProc);

    switch(message)
    {
        case WM_COMMAND:
            switch(LOWORD(wParam))
            {
                case ID_OBJECTS_OPENMODULE:
                    LoadNewModule();
                    break;

                case ID_OBJECTS_UNLOADMODULE:
                    {
                        DWORD dwCurSel = SendMessage(hwndModuleList, LB_GETCURSEL, 0, 0);

                        if(dwCurSel != LB_ERR)
                        {
                            if(MessageBox(hwndModuleList, TEXT("Unloading a module will remove all objects associated with this module from this level.\r\n\r\nAre you sure you want to do this?"), TEXT("Unload Module"), MB_YESNO|MB_ICONQUESTION) == IDYES)
                            {
                                String strModuleName;
                                strModuleName.SetLength(255);
                                SendMessage(hwndModuleList, LB_GETTEXT, dwCurSel, (LPARAM)(CTSTR)strModuleName);

                                SendMessage(hwndModuleList, LB_DELETESTRING, dwCurSel, 0);

                                level->UnloadLevelModule(strModuleName);

                                UpdateObjectTreeAndModules();
                            }
                        }
                        else
                            MessageBox(hwnd, TEXT("You have to select a module to unload."), NULL, MB_OK);

                        break;
                    }

                case ID_OBJECTS_CLOSE:
                    DestroyWindow(hwnd);
                    editor->hwndObjectBrowser = NULL;
                    break;
            }
            break;

        case WM_NOTIFY:
            {
                NMTREEVIEW *info = (NMTREEVIEW*)lParam;

                if(info->hdr.code == TVN_SELCHANGED)
                {
                    HTREEITEM hItem = TreeView_GetSelection(hwndObjectTree);

                    TVITEMEX tvi;

                    zero(&tvi, sizeof(tvi));
                    tvi.mask  = TVIF_PARAM|TVIF_HANDLE;
                    tvi.hItem = hItem;
                    TreeView_GetItem(hwndObjectTree, &tvi);

                    Class *cls = (Class*)tvi.lParam;

                    editor->selectedEntityClass = cls;

                    if((levelInfo->curEditMode == EditMode_Create) && levelInfo->newObject && levelInfo->newObject->IsOf(GetClass(EntityPlacer)))
                    {
                        EntityPlacer *ep = (EntityPlacer*)levelInfo->newObject;
                        EditMode em = ep->prevEditMode;
                        EntityType et = ep->entityType;

                        delete levelInfo->newObject;
                        levelInfo->newObject = CreateObjectParam2(EntityPlacer, em, et);
                    }
                }

                break;
            }

        case WM_SIZE:
            {
                int cx = LOWORD(lParam);
                int cy = HIWORD(lParam);

                SetWindowPos(hwndObjectTree, NULL, 150, 0, cx-150, cy, SWP_NOMOVE);
                SetWindowPos(hwndModuleList, NULL, 0, 0, 150, cy, SWP_NOMOVE);
                break;
            }

        case WM_SIZING:
            {
                int borderXSize = 300;
                int borderYSize = 300;

                borderXSize += GetSystemMetrics(SM_CXSIZEFRAME)*2;
                borderYSize += GetSystemMetrics(SM_CYSIZEFRAME)*2;
                borderYSize += GetSystemMetrics(SM_CYCAPTION);
                borderYSize += GetSystemMetrics(SM_CYMENU);

                RECT *pRect = (RECT*)lParam;

                if((pRect->right - pRect->left) <= borderXSize)
                    pRect->right = pRect->left + borderXSize;

                if((pRect->bottom - pRect->top) <= borderYSize)
                    pRect->bottom = pRect->top + borderYSize;

                return TRUE;
            }

        case WM_CLOSE:
            DestroyWindow(hwnd);
            editor->hwndObjectBrowser = NULL;
            break;
    }

    return DefWindowProc(hwnd, message, wParam, lParam);

    traceOut;
}
Example #18
0
BOOL CALLBACK OpenModuleDialogProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    traceIn(OpenModuleDialogProc);

    switch(message)
    {
        case WM_INITDIALOG:
            {
                OSFindData findData;

                //todo: 
                AppWarning(TEXT("fix this thingy please"));
                HANDLE hFind = OSFindFirstFile(TEXT("*.xxt"), findData);

                if(hFind)
                {
                    do
                    {
                        findData.fileName[slen(findData.fileName)-4] = 0;
                        if(!IsModuleLoaded(findData.fileName))
                            SendMessage(GetDlgItem(hwnd, IDC_MODULELIST), LB_ADDSTRING, 0, (LPARAM)findData.fileName);
                    }while(OSFindNextFile(hFind, findData));

                    OSFindClose(hFind);

                    SendMessage(GetDlgItem(hwnd, IDC_MODULELIST), LB_SETCURSEL, 0, 0);
                    SendMessage(GetDlgItem(hwnd, IDC_MODULELIST), EM_LIMITTEXT, 250, 0);
                }
                break;
            }

        case WM_COMMAND:
            switch(LOWORD(wParam))
            {
                case IDC_MODULELIST:
                    if(HIWORD(wParam) == LBN_DBLCLK)
                        PostMessage(hwnd, WM_COMMAND, MAKEWPARAM(IDOK, BN_CLICKED), lParam);
                    break;

                case IDOK:
                    {
                        DWORD dwCurSel = SendMessage(GetDlgItem(hwnd, IDC_MODULELIST), LB_GETCURSEL, 0, 0);

                        if(dwCurSel != LB_ERR)
                        {
                            String strModuleName;
                            strModuleName.SetLength(255);
                            SendMessage(GetDlgItem(hwnd, IDC_MODULELIST), LB_GETTEXT, dwCurSel, (LPARAM)(CTSTR)strModuleName);

                            if(!level->LoadLevelModule(strModuleName))
                                MessageBox(hwnd, String() << TEXT("Unable to open module '") << strModuleName << TEXT("'."), NULL, MB_OK);
                            else
                            {
                                EndDialog(hwnd, IDOK);
                                UpdateObjectTreeAndModules();
                            }
                        }
                        else
                            MessageBox(hwnd, TEXT("You need to select a module first"), NULL, MB_OK);

                        break;
                    }

                case IDCANCEL:
                    EndDialog(hwnd, IDCANCEL);
                    break;
            }
            break;

        case WM_CLOSE:
            EndDialog(hwnd, IDCANCEL);
            break;
    }

    return FALSE;

    traceOut;
}
Example #19
0
bool OBS::SetScene(CTSTR lpScene)
{
    if(bDisableSceneSwitching)
        return false;

    HWND hwndScenes = GetDlgItem(hwndMain, ID_SCENES);
    UINT curSel = (UINT)SendMessage(hwndScenes, LB_GETCURSEL, 0, 0);

    //-------------------------

    if(curSel != LB_ERR)
    {
        UINT textLen = (UINT)SendMessage(hwndScenes, LB_GETTEXTLEN, curSel, 0);

        String strLBName;
        strLBName.SetLength(textLen);

        SendMessage(hwndScenes, LB_GETTEXT, curSel, (LPARAM)strLBName.Array());
        if(!strLBName.CompareI(lpScene))
        {
            UINT id = (UINT)SendMessage(hwndScenes, LB_FINDSTRINGEXACT, -1, (LPARAM)lpScene);
            if(id == LB_ERR)
                return false;

            SendMessage(hwndScenes, LB_SETCURSEL, id, 0);
        }
    }
    else
    {
        UINT id = (UINT)SendMessage(hwndScenes, LB_FINDSTRINGEXACT, -1, (LPARAM)lpScene);
        if(id == LB_ERR)
            return false;

        SendMessage(hwndScenes, LB_SETCURSEL, id, 0);
    }

    //-------------------------

    XElement *scenes = scenesConfig.GetElement(TEXT("scenes"));
    XElement *newSceneElement = scenes->GetElement(lpScene);
    if(!newSceneElement)
        return false;

    if(sceneElement == newSceneElement)
        return true;

    sceneElement = newSceneElement;

    CTSTR lpClass = sceneElement->GetString(TEXT("class"));
    if(!lpClass)
    {
        AppWarning(TEXT("OBS::SetScene: no class found for scene '%s'"), newSceneElement->GetName());
        return false;
    }

    DWORD sceneChangeStartTime;

    if(bRunning)
    {
        Log(TEXT("++++++++++++++++++++++++++++++++++++++++++++++++++++++"));
        Log(TEXT("  New Scene"));

        sceneChangeStartTime = OSGetTime();
    }

    XElement *sceneData = newSceneElement->GetElement(TEXT("data"));

    //-------------------------

    Scene *newScene = NULL;
    if(bRunning)
        newScene = CreateScene(lpClass, sceneData);

    //-------------------------

    HWND hwndSources = GetDlgItem(hwndMain, ID_SOURCES);

    SendMessage(hwndSources, WM_SETREDRAW, (WPARAM)FALSE, (LPARAM) 0);

    App->scaleItem = NULL;

    bChangingSources = true;
    ListView_DeleteAllItems(hwndSources);

    bool bSkipTransition = false;

    XElement *sources = sceneElement->GetElement(TEXT("sources"));
    if(sources)
    {
        UINT numSources = sources->NumElements();
        ListView_SetItemCount(hwndSources, numSources);

        for(UINT i=0; i<numSources; i++)
        {
            XElement *sourceElement = sources->GetElementByID(i);
            String className = sourceElement->GetString(TEXT("class"));

            if(className == "DeviceCapture") {
                // There's a capture device in the next scene that isn't a global source,
                // so let's skip the transition since it won't work anyway.
                bSkipTransition = true;
            }
        }

        for(UINT i=0; i<numSources; i++)
        {
            XElement *sourceElement = sources->GetElementByID(i);
            bool render = sourceElement->GetInt(TEXT("render"), 1) > 0;

            InsertSourceItem(i, (LPWSTR)sourceElement->GetName(), render);

            // Do not add image sources yet in case we're skipping the transition.
            // This fixes the issue where capture devices sources that used the
            // same device as one in the previous scene would just go blank
            // after switching.
            if(bRunning && newScene && !bSkipTransition)
                newScene->AddImageSource(sourceElement);
        }
    }

    bChangingSources = false;
    SendMessage(hwndSources, WM_SETREDRAW, (WPARAM)TRUE, (LPARAM) 0);
    RedrawWindow(hwndSources, NULL, NULL, RDW_ERASE | RDW_FRAME | RDW_INVALIDATE | RDW_ALLCHILDREN);

    if(scene && newScene && newScene->HasMissingSources())
        MessageBox(hwndMain, Str("Scene.MissingSources"), NULL, 0);

    if(bRunning)
    {
        //todo: cache scenes maybe?  undecided.  not really as necessary with global sources
        OSEnterMutex(hSceneMutex);

        UINT numSources;

        if (scene)
        {
            //shutdown previous scene, if any
            numSources = scene->sceneItems.Num();
            for(UINT i=0; i<numSources; i++)
            {
                XElement *source = scene->sceneItems[i]->GetElement();
                String className = source->GetString(TEXT("class"));
                if(scene->sceneItems[i]->bRender && className == "GlobalSource") {
                    XElement *globalSourceData = source->GetElement(TEXT("data"));
                    String globalSourceName = globalSourceData->GetString(TEXT("name"));
                    if(App->GetGlobalSource(globalSourceName) != NULL) {
                        App->GetGlobalSource(globalSourceName)->GlobalSourceLeaveScene();
                    }
                }
            }

            scene->EndScene();
        }

        Scene *previousScene = scene;
        scene = newScene;

        if(newScene && bSkipTransition) {
            // If we're skipping the transition because of a non-global
            // DirectShow device, delete the scene here and add the
            // ImageSources at this point instead.
            delete previousScene;

            if(sources)
            {
                UINT numSources = sources->NumElements();

                for(UINT i=0; i<numSources; i++)
                {
                    XElement *sourceElement = sources->GetElementByID(i);

                    if(newScene)
                        newScene->AddImageSource(sourceElement);
                }
            }
        }

        scene->BeginScene();

        numSources = scene->sceneItems.Num();
        for(UINT i=0; i<numSources; i++)
        {
            XElement *source = scene->sceneItems[i]->GetElement();

            String className = source->GetString(TEXT("class"));
            if(scene->sceneItems[i]->bRender && className == "GlobalSource") {
                XElement *globalSourceData = source->GetElement(TEXT("data"));
                String globalSourceName = globalSourceData->GetString(TEXT("name"));
                if(App->GetGlobalSource(globalSourceName) != NULL) {
                    App->GetGlobalSource(globalSourceName)->GlobalSourceEnterScene();
                }
            }
        }

        if(!bTransitioning && !bSkipTransition)
        {
            bTransitioning = true;
            transitionAlpha = 0.0f;
        }

        OSLeaveMutex(hSceneMutex);

        if(!bSkipTransition) {
            // Do not delete the previous scene here, since it has already
            // been deleted.
            delete previousScene;
        }

        DWORD sceneChangeTime = OSGetTime() - sceneChangeStartTime;
        if (sceneChangeTime >= 500)
            Log(TEXT("PERFORMANCE WARNING: Scene change took %u ms, maybe some sources should be global sources?"), sceneChangeTime);
    }

    if(API != NULL)
       ReportSwitchScenes(lpScene);

    return true;
}
Example #20
0
DWORD WINAPI RTMPPublisher::CreateConnectionThread(RTMPPublisher *publisher)
{
    //------------------------------------------------------
    // set up URL

    bool bRetry = false;
    bool bSuccess = false;
    bool bCanRetry = false;

    String failReason;
    String strBindIP;

    int    serviceID    = AppConfig->GetInt   (TEXT("Publish"), TEXT("Service"));
    String strURL       = AppConfig->GetString(TEXT("Publish"), TEXT("URL"));
    String strPlayPath  = AppConfig->GetString(TEXT("Publish"), TEXT("PlayPath"));

    strURL.KillSpaces();
    strPlayPath.KillSpaces();

    LPSTR lpAnsiURL = NULL, lpAnsiPlaypath = NULL;
    RTMP *rtmp = NULL;

    //--------------------------------
    // unbelievably disgusting hack for elgato devices

    String strOldDirectory;
    UINT dirSize = GetCurrentDirectory(0, 0);
    strOldDirectory.SetLength(dirSize);
    GetCurrentDirectory(dirSize, strOldDirectory.Array());

    OSSetCurrentDirectory(API->GetAppPath());

    //--------------------------------

    if(!strURL.IsValid())
    {
        failReason = TEXT("No server specified to connect to");
        goto end;
    }

    if(serviceID != 0)
    {
        XConfig serverData;
        if(!serverData.Open(TEXT("services.xconfig")))
        {
            failReason = TEXT("Could not open services.xconfig");
            goto end;
        }

        XElement *services = serverData.GetElement(TEXT("services"));
        if(!services)
        {
            failReason = TEXT("Could not find any services in services.xconfig");
            goto end;
        }

        XElement *service = NULL;
        DWORD numServices = services->NumElements();
        for(UINT i=0; i<numServices; i++)
        {
            XElement *curService = services->GetElementByID(i);
            if(curService->GetInt(TEXT("id")) == serviceID)
            {
                service = curService;
                break;
            }
        }

        if(!service)
        {
            failReason = TEXT("Could not find the service specified in services.xconfig");
            goto end;
        }

        XElement *servers = service->GetElement(TEXT("servers"));
        if(!servers)
        {
            failReason = TEXT("Could not find any servers for the service specified in services.xconfig");
            goto end;
        }

        XDataItem *item = servers->GetDataItem(strURL);
        if(!item)
            item = servers->GetDataItemByID(0);

        strURL = item->GetData();

        Log(TEXT("Using RTMP service: %s"), service->GetName());
        Log(TEXT("  Server selection: %s"), strURL.Array());
    }

    //------------------------------------------------------
    // now back to the elgato directory if it needs the directory changed still to function *sigh*

    OSSetCurrentDirectory(strOldDirectory);

    //------------------------------------------------------

    rtmp = RTMP_Alloc();
    RTMP_Init(rtmp);

    RTMP_LogSetCallback(librtmpErrorCallback);

    //RTMP_LogSetLevel(RTMP_LOGERROR);

    lpAnsiURL = strURL.CreateUTF8String();
    lpAnsiPlaypath = strPlayPath.CreateUTF8String();

    if(!RTMP_SetupURL2(rtmp, lpAnsiURL, lpAnsiPlaypath))
    {
        failReason = Str("Connection.CouldNotParseURL");
        goto end;
    }

    char *rtmpUser = AppConfig->GetString(TEXT("Publish"), TEXT("Username")).CreateUTF8String();
    char *rtmpPass = AppConfig->GetString(TEXT("Publish"), TEXT("Password")).CreateUTF8String();

    if (rtmpUser)
    {
        rtmp->Link.pubUser.av_val = rtmpUser;
        rtmp->Link.pubUser.av_len = (int)strlen(rtmpUser);
    }

    if (rtmpPass)
    {
        rtmp->Link.pubPasswd.av_val = rtmpPass;
        rtmp->Link.pubPasswd.av_len = (int)strlen(rtmpPass);
    }

    RTMP_EnableWrite(rtmp); //set it to publish

    rtmp->Link.swfUrl.av_len = rtmp->Link.tcUrl.av_len;
    rtmp->Link.swfUrl.av_val = rtmp->Link.tcUrl.av_val;
    /*rtmp->Link.pageUrl.av_len = rtmp->Link.tcUrl.av_len;
    rtmp->Link.pageUrl.av_val = rtmp->Link.tcUrl.av_val;*/
    rtmp->Link.flashVer.av_val = "FMLE/3.0 (compatible; FMSc/1.0)";
    rtmp->Link.flashVer.av_len = (int)strlen(rtmp->Link.flashVer.av_val);

    //-----------------------------------------

    UINT tcpBufferSize = AppConfig->GetInt(TEXT("Publish"), TEXT("TCPBufferSize"), 64*1024);

    if(tcpBufferSize < 8192)
        tcpBufferSize = 8192;
    else if(tcpBufferSize > 1024*1024)
        tcpBufferSize = 1024*1024;

    rtmp->m_outChunkSize = 4096;//RTMP_DEFAULT_CHUNKSIZE;//
    rtmp->m_bSendChunkSizeInfo = TRUE;

    rtmp->m_bUseNagle = TRUE;

    strBindIP = AppConfig->GetString(TEXT("Publish"), TEXT("BindToIP"), TEXT("Default"));
    if (scmp(strBindIP, TEXT("Default")))
    {
        rtmp->m_bindIP.addr.sin_family = AF_INET;
        rtmp->m_bindIP.addrLen = sizeof(rtmp->m_bindIP.addr);
        if (WSAStringToAddress(strBindIP.Array(), AF_INET, NULL, (LPSOCKADDR)&rtmp->m_bindIP.addr, &rtmp->m_bindIP.addrLen) == SOCKET_ERROR)
        {
            // no localization since this should rarely/never happen
            failReason = TEXT("WSAStringToAddress: Could not parse address");
            goto end;
        }
    }

    LogInterfaceType(rtmp);

    //-----------------------------------------

    DWORD startTime = OSGetTime();

    if(!RTMP_Connect(rtmp, NULL))
    {
        failReason = Str("Connection.CouldNotConnect");
        failReason << TEXT("\r\n\r\n") << RTMPPublisher::GetRTMPErrors();
        bCanRetry = true;
        goto end;
    }

    Log(TEXT("Completed handshake with %s in %u ms."), strURL.Array(), OSGetTime() - startTime);

    if(!RTMP_ConnectStream(rtmp, 0))
    {
        failReason = Str("Connection.InvalidStream");
        failReason << TEXT("\r\n\r\n") << RTMPPublisher::GetRTMPErrors();
        bCanRetry = true;
        goto end;
    }

    //-----------------------------------------

    OSDebugOut(TEXT("Connected: %u\r\n"), OSGetTime());

    publisher->RequestKeyframe(1000);

    //-----------------------------------------

    bSuccess = true;

end:

    if (lpAnsiURL)
        Free(lpAnsiURL);

    if (lpAnsiPlaypath)
        Free(lpAnsiPlaypath);

    if(!bSuccess)
    {
        if(rtmp)
        {
            RTMP_Close(rtmp);
            RTMP_Free(rtmp);
        }

        if(failReason.IsValid())
            App->SetStreamReport(failReason);

        if(!publisher->bStopping)
            PostMessage(hwndMain, OBS_REQUESTSTOP, bCanRetry ? 0 : 1, 0);

        Log(TEXT("Connection to %s failed: %s"), strURL.Array(), failReason.Array());

        publisher->bStopping = true;
    }
    else
    {
        publisher->Init(rtmp, tcpBufferSize);
        publisher->bConnected = true;
        publisher->bConnecting = false;
    }

    return 0;
}