📄 hxbackend.cpp
字号:
/* Player failed to exit, kill it */#ifdef DEBUG ShowError("Player failed to exit");#endif kill(m_nChildPid, SIGTERM); } if(bExited) { /* Keep in mind that our child process here is a bourne shell. sh will return the exit code of the last process to exit, or 128 + the signal number if it was killed by a signal. */ int nTermSig = WTERMSIG(nStatus); int nExitStatus = WEXITSTATUS(nStatus); if(nTermSig != 0 || nExitStatus != 0) { if(nTermSig == 0 && nExitStatus == EXIT_CODE_HXPLAY_NOT_FOUND) { /* Not found */ } else { char *pMsg; if(nTermSig) { /* Our shell has crashed... */ asprintf(&pMsg, "Player's shell exited with signal %d", nTermSig); } else if(nExitStatus > 128) { // sh will return 128 + signal number nTermSig = nExitStatus - 128; asprintf(&pMsg, "Player exited with signal %d", nTermSig); } else { // player exited abnormally. The shell executing the // hxplay script will propagate this error code to us. asprintf(&pMsg, "Player exited with code %d", nExitStatus); } ShowError(pMsg); free(pMsg); } } } m_nChildPid = 0; } m_bEmbeddedPlayerOpen = FALSE;}void CHXPlayerBackend::Shutdown(PRBool bSendShutdownCommand){ if(m_bPlayerShutdown) { return; } m_bPlayerShutdown = PR_TRUE; /* Kill the timer -- it can call Shutdown while we're in some of the dialogs below, which confuses us. */ StopCallbackTimer(); CHXTimerFob* pTimerFob = new CHXTimerFob; NS_ADDREF(pTimerFob); if(m_pTimer) { m_pTimer->Cancel(); /* Re-initing causes the timer to unref this and switch its ref to pTimerFob instead */ m_pTimer->Init(pTimerFob, 500, nsIScriptableTimer::TYPE_REPEATING_SLACK); m_pTimer->Cancel(); NS_RELEASE(m_pTimer); m_pTimer = NULL; } if(m_pObsoleteTimer) { m_pObsoleteTimer->Cancel(); /* Re-initing causes the timer to unref this and switch its ref to pTimerFob instead */ m_pObsoleteTimer->Init(pTimerFob, 500, nsIScriptableTimer::PRIORITY_NORMAL, nsIScriptableTimer::TYPE_REPEATING_SLACK); m_pObsoleteTimer->Cancel(); NS_RELEASE(m_pObsoleteTimer); m_pObsoleteTimer = NULL; } NS_RELEASE(pTimerFob); CloseEmbeddedPlayer(bSendShutdownCommand); /* Release components and services */ NS_IF_RELEASE(m_pPromptService); NS_IF_RELEASE(m_pUConv); NS_IF_RELEASE(m_pMemory); if(m_fdApi != -1) { close(m_fdApi); } if(m_fdCallback != -1) { close(m_fdCallback); } m_fdApi = -1; m_fdCallback = -1; if(m_pCallbackBuf) { free(m_pCallbackBuf); m_nCallbackBufLen = 0; m_nCallbackBufPos = 0; } if(m_pPlayersList) { free(m_pPlayersList); m_nPlayerCount = 0; m_nMaxPlayers = 0; }}void CHXPlayerBackend::AddHXPlayer(nsHXPlayer *pPlayer){ /* We could add reference counting here. */ if(!m_pPlayersList) { m_nMaxPlayers = 10; m_pPlayersList = (nsHXPlayer**)calloc(m_nMaxPlayers, m_nMaxPlayers * sizeof(nsHXPlayer*)); } m_pPlayersList[m_nPlayerCount++] = pPlayer; if(m_nPlayerCount <= m_nMaxPlayers) { m_nMaxPlayers *= 2; m_pPlayersList = (nsHXPlayer**)realloc(m_pPlayersList, m_nMaxPlayers * sizeof(*m_pPlayersList)); }}void CHXPlayerBackend::RemoveHXPlayer(nsHXPlayer *pPlayer){ int i; for(i = 0; i < m_nPlayerCount; i++) { if(pPlayer == m_pPlayersList[i]) { m_pPlayersList[i] = m_pPlayersList[m_nPlayerCount - 1]; m_nPlayerCount--; return; } } printf("Cannot find player in RemoveHXPlayer\n");}void CHXPlayerBackend::ProcessCallback(const char *szCallback){ /* callbacks are of this format: Callback name, callback, parameterlist */ CStringTokenizer tokenizer(szCallback); char *szType = NULL; char *szUrl = NULL; char *szTarget = NULL; nsHXPlayer* pPlayer = NULL; int i; szType = tokenizer.NextToken(); if(strcmp(szType, "Callback") == 0) { char *szName; char *szCallback; char *szParams; szName = tokenizer.NextToken(); szCallback = tokenizer.NextToken(); szParams = tokenizer.RemainingChars(); asprintf(&szUrl, "javascript:%s_%s(%s)", szName, szCallback, szParams); szTarget = strdup("_self"); /* find a player with matching name */ for(i = 0; i < m_nPlayerCount; i++) { if(strcasecmp(m_pPlayersList[i]->GetName(), szName) == 0) { pPlayer = m_pPlayersList[i]; break; } } free(szName); free(szCallback); free(szParams); } else if(strcmp(szType, "GetURL") == 0) { char *szPlayerId; int nPlayerId; szPlayerId = tokenizer.NextToken(); // must be the player ID nPlayerId = atoi(szPlayerId); free(szPlayerId); for(i = 0; i < m_nPlayerCount; i++) { if(m_pPlayersList[i]->GetId() == nPlayerId) { pPlayer = m_pPlayersList[i]; break; } } szUrl = tokenizer.NextToken(); // must be the URL szTarget = tokenizer.NextToken(); // must be the target } else { printf("Unknown command %s\n", szType); } if(szType) { free(szType); } if(szUrl && szTarget && pPlayer) { pPlayer->OnGetURL(szUrl, szTarget); } if(szUrl) { free(szUrl); } if(szTarget) { free(szTarget); }}nsresult CHXPlayerBackend::PollForCallbacks(void){ /* Poll for data on the callback descriptor */ ssize_t nResult; fd_set fdsRead, fdsException; struct timeval timeout; int nDescriptors; nsresult result = NS_OK; char c; if(m_bPlayerShutdown || !m_bEmbeddedPlayerOpen) { return NS_ERROR_FAILURE; } for(;;) { FD_ZERO(&fdsRead); FD_ZERO(&fdsException); FD_SET(m_fdCallback, &fdsRead); FD_SET(m_fdCallback, &fdsException); /* Return immediately */ timeout.tv_sec = 0; timeout.tv_usec = 0; nDescriptors = select(m_fdCallback + 1, &fdsRead, NULL, &fdsException, &timeout); if(nDescriptors < 0) { perror("select"); break; } else if(nDescriptors == 0) { /* No more data available */ break; } else { if(FD_ISSET(m_fdCallback, &fdsException)) { /* This should never happen. */ printf("Exception in playeripc_parse_commands"); result = NS_ERROR_FAILURE; break; } else if(FD_ISSET(m_fdCallback, &fdsRead)) { /* We can read */ nResult = read(m_fdCallback, &c, 1); if(nResult <= 0) { if(nResult < 0) { if((errno != EINTR) && (errno != EAGAIN)) { perror("read"); result = NS_ERROR_FAILURE; } } /* Connection closed */ result = NS_ERROR_FAILURE; CloseEmbeddedPlayer(PR_FALSE); break; } else { if(c == '\n') { m_pCallbackBuf[m_nCallbackBufPos] = '\0'; ProcessCallback(m_pCallbackBuf); m_nCallbackBufPos = 0; } else { m_pCallbackBuf[m_nCallbackBufPos++] = c; if(m_nCallbackBufPos >= m_nCallbackBufLen) { /* We need more buffer space */ m_nCallbackBufLen *= 2; m_pCallbackBuf = (char*)realloc(m_pCallbackBuf, m_nCallbackBufLen * sizeof(char)); } } } } else { /* This is unreachable. */ printf("Unknown state in select()\n"); result = NS_ERROR_FAILURE; break; } } } return NS_OK;}void CHXPlayerBackend::StartCallbackTimer(){ if (m_pTimer) { m_bCallbackTimerRunning = PR_TRUE; m_pTimer->Init(this, 500, nsITimer::TYPE_REPEATING_SLACK); } else if(m_pObsoleteTimer) { m_bCallbackTimerRunning = PR_TRUE; m_pObsoleteTimer->Init(this, 500, nsIScriptableTimer::PRIORITY_NORMAL, nsIScriptableTimer::TYPE_REPEATING_SLACK); }}void CHXPlayerBackend::StopCallbackTimer(){ if(m_pTimer) { m_bCallbackTimerRunning = PR_FALSE; m_pTimer->Cancel(); } if(m_pObsoleteTimer) { m_bCallbackTimerRunning = PR_FALSE; m_pObsoleteTimer->Cancel(); }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -