/** Plays stereo data out the speakers */ void playStereoData(playData* d) { if (paNoError != Pa_Initialize()) throwerror("Port audio failed to initialise."); //initialise port audio //setup port audio output device PaStreamParameters outputParameters; outputParameters.device = Pa_GetDefaultOutputDevice(); //get default port audio output device if (outputParameters.device == paNoDevice) throwerror("Error: No default output device."); outputParameters.channelCount = 2; // stereo output outputParameters.sampleFormat = paFloat32; // 32 bit floating point output outputParameters.suggestedLatency = Pa_GetDeviceInfo(outputParameters.device)->defaultLowOutputLatency; outputParameters.hostApiSpecificStreamInfo = NULL; PaStream *stream; Pa_OpenStream( &stream, NULL, /* no input */ &outputParameters, d->sampleRate, buffer_size, paClipOff, /* we won't output out of range samples so don't bother clipping them */ playCallback, d); if (paNoError != Pa_StartStream(stream)) throwerror("Port audio stream failed to start."); //sleep until stream is finished (up to 200 millisecond delay at end) while (Pa_IsStreamActive(stream)) Pa_Sleep(200); if (paNoError != Pa_StopStream(stream)) throwerror("Port audio stream failed to stop."); //were finished close the stream and terminate port audio if (paNoError != Pa_CloseStream(stream)) throwerror("Port audio fail to initialise."); Pa_Terminate(); }
int main(int argc, char *argv[]) { if (!MainInit(argc, argv)) { printf("Error: %s\n", GetTranslation("Init failed, aborting")); return 1; } // Init if (!(MainWin = initscr())) throwerror(false, "Could not init ncurses"); if (!(CDKScreen = initCDKScreen(MainWin))) throwerror(false, "Could not init CDK"); initCDKColor(); if ((InstallInfo.dest_dir_type == DEST_DEFAULT) && !ReadAccess(InstallInfo.dest_dir)) throwerror(true, CreateText("This installer will install files to the following directory:\n%s\n" "However you don't have read permissions to this directory\n" "Please restart the installer as a user who does or as the root user", InstallInfo.dest_dir.c_str())); int i=0; while(Functions[i]) { if (Functions[i]()) i++; else { if (YesNoBox(GetTranslation("This will abort the installation\nAre you sure?"))) break; } } EndProg(); return 0; }
CCDKLabel::CCDKLabel(CDKSCREEN *pScreen, int x, int y, const char *msg, bool box, bool shadow) : CBaseCDKWidget(box) { char *sz[1] = { const_cast<char*>(msg) }; m_pLabel = newCDKLabel(pScreen, x, y, sz, 1, box, shadow); if (!m_pLabel) throwerror(false, "Could not create text label"); }
CCDKDialog::CCDKDialog(CDKSCREEN *pScreen, int x, int y, const std::string &message, char **buttons, int bcount, chtype hlight, bool sep, bool box, bool shadow) : CBaseCDKWidget(box) { //std::vector<char *> vec(1, const_cast<char *>(message.c_str())); std::vector<char *> vec; MakeStringList(message, vec); m_pDialog = newCDKDialog(pScreen, x, y, &vec[0], vec.size(), buttons, bcount, hlight, sep, box, shadow); if (!m_pDialog) throwerror(false, "Could not create dialog window"); }
void CButtonBar::Draw() { if (!m_pCurrentBarEntry) return; if (!m_pCurrentBarEntry->szCurrentText.empty()) { m_pCurrentBarEntry->Texts.push_back(MakeCString(m_pCurrentBarEntry->szCurrentText)); m_pCurrentBarEntry->szCurrentText.clear(); m_pCurrentBarEntry->iCurTextLength = 0; } if (m_pCurrentBarEntry->Texts.empty()) return; if (m_pLabel) delete m_pLabel; // CDK has no propper way to change text... m_pLabel = new CCDKLabel(CDKScreen, CENTER, BOTTOM, &m_pCurrentBarEntry->Texts[0], m_pCurrentBarEntry->Texts.size()); if (!m_pLabel) throwerror(false, "Could not create button bar"); m_pLabel->SetBgColor(24); m_pLabel->Draw(); refreshCDKScreen(CDKScreen); }
bool SelectLanguage() { if (InstallInfo.languages.size() == 1) { InstallInfo.cur_lang = InstallInfo.languages.front(); if (!ReadLang()) throwerror(true, "Could not load language file for %s", InstallInfo.cur_lang.c_str()); return true; } char title[] = "<C></B/29>Please select a language<!29!B>"; std::vector<char *> LangItems; ButtonBar.Clear(); ButtonBar.AddButton("Arrows", "Navigate menu"); ButtonBar.AddButton("A", "About"); ButtonBar.AddButton("ESC", "Exit program"); ButtonBar.Draw(); for (std::list<std::string>::iterator p=InstallInfo.languages.begin();p!=InstallInfo.languages.end();p++) LangItems.push_back(MakeCString(*p)); CCDKScroll ScrollList(CDKScreen, CENTER, CENTER, GetMaxHeight(20), GetMaxWidth(45), RIGHT, title, &LangItems[0], LangItems.size()); ScrollList.SetBgColor(5); ScrollList.Bind('a', ShowAboutK); int selection = ScrollList.Activate(); if (ScrollList.ExitType() == vNORMAL) { InstallInfo.cur_lang = LangItems[selection]; ReadLang(); } else return false; return true; }
bool InstallFiles() { ButtonBar.Clear(); ButtonBar.AddButton("C", "Cancel"); ButtonBar.Draw(); char *msg; char *dbuttons[2] = { GetTranslation("Continue"), GetTranslation("Exit program") }; if ((InstallInfo.dest_dir_type == DEST_SELECT) || (InstallInfo.dest_dir_type == DEST_DEFAULT)) { msg = CreateText(GetTranslation("This will install %s to the following directory:\n%s\nContinue?"), InstallInfo.program_name.c_str(), MakeCString(InstallInfo.dest_dir)); } else { msg = CreateText(GetTranslation("This will install %s\nContinue?"), InstallInfo.program_name.c_str()); } CCDKDialog Diag(CDKScreen, CENTER, CENTER, msg, dbuttons, 2); Diag.SetBgColor(26); int sel = Diag.Activate(); Diag.Destroy(); refreshCDKScreen(CDKScreen); if (sel == 1) return false; CCDKSWindow InstallOutput(CDKScreen, 0, 6, GetDefaultHeight()-5, -1, CreateText("<C></29/B>%s", GetTranslation("Install output")), 2000); InstallOutput.SetBgColor(5); nodelay(WindowOf(InstallOutput.GetSWin()), true); // Make sure input doesn't block const int maxx = getmaxx(InstallOutput.GetSWin()->win); CCDKSWindow ProggWindow(CDKScreen, 0, 2, 5, maxx, NULL, 4); ProggWindow.SetBgColor(5); ProggWindow.AddText(""); ProggWindow.AddText(CreateText("</B/29>%s:<!29!B>", GetTranslation("Status"))); ProggWindow.AddText(CreateText("%s (1/%d)", GetTranslation("Extracting files"), InstallInfo.command_entries.size()+1), true, BOTTOM, 24); CCDKHistogram ProgressBar(CDKScreen, 25, 3, 1, maxx-29, HORIZONTAL, CreateText("<C></29/B>%s", GetTranslation("Progress")), false); ProgressBar.SetBgColor(5); ProgressBar.SetHistogram(vPERCENT, TOP, 0, 100, 0, COLOR_PAIR (24) | A_REVERSE | ' ', A_BOLD); setCDKSwindowLLChar(ProggWindow.GetSWin(), ACS_LTEE); setCDKSwindowLRChar(ProggWindow.GetSWin(), ACS_RTEE); InstallOutput.Draw(); ProggWindow.Draw(); // Check if we need root access char *passwd = NULL; LIBSU::CLibSU SuHandler; SuHandler.SetUser("root"); SuHandler.SetTerminalOutput(false); bool askpass = false; for (std::list<command_entry_s *>::iterator it=InstallInfo.command_entries.begin(); it!=InstallInfo.command_entries.end(); it++) { if ((*it)->need_root != NO_ROOT) { // Command may need root permission, check if it is so if ((*it)->need_root == DEPENDED_ROOT) { param_entry_s *p = GetParamByVar((*it)->dep_param); if (p && !WriteAccess(p->value)) { (*it)->need_root = NEED_ROOT; if (!askpass) askpass = true; } } else if (!askpass) askpass = true; } } if (!askpass) askpass = !WriteAccess(InstallInfo.dest_dir); // Ask root password if one of the command entries need root access and root isn't passwordless if (askpass && SuHandler.NeedPassword()) { CCDKEntry entry(CDKScreen, CENTER, CENTER, GetTranslation("This installation requires root(administrator) privileges in order to continue\n" "Please enter the password of the root user"), "", 60, 0, 256, vHMIXED); entry.SetHiddenChar('*'); entry.SetBgColor(26); while(1) { char *sz = entry.Activate(); if ((entry.ExitType() != vNORMAL) || !sz || !sz[0]) { if (YesNoBox(GetTranslation("Root access is required to continue\nAbort installation?"))) EndProg(); refreshCDKScreen(CDKScreen); } else { if (SuHandler.TestSU(sz)) { passwd = strdup(sz); for (short s=0;s<strlen(sz);s++) sz[s] = 0; break; } for (short s=0;s<strlen(sz);s++) sz[s] = 0; entry.Clean(); // Some error appeared if (SuHandler.GetError() == LIBSU::CLibSU::SU_ERROR_INCORRECTPASS) { WarningBox(GetTranslation("Incorrect password given for root user\nPlease retype")); } else { throwerror(true, GetTranslation("Could not use su to gain root access\n" "Make sure you can use su(adding the current user to the wheel group may help)")); } } } // Restore screen entry.Destroy(); refreshCDKScreen(CDKScreen); } short percent = 0; bool alwaysroot = false; if (!WriteAccess(InstallInfo.dest_dir)) { CExtractAsRootFunctor Extracter; Extracter.SetUpdateProgFunc(SUUpdateProgress, &ProgressBar); Extracter.SetUpdateTextFunc(SUUpdateText, &InstallOutput); if (!Extracter(passwd)) { CleanPasswdString(passwd); passwd = NULL; throwerror(true, "Error during extracting files"); } InstallOutput.AddText("Done!\n"); alwaysroot = true; // Install commands need root now too } else { while(percent<100) { std::string curfile; percent = ExtractArchive(curfile); InstallOutput.AddText("Extracting file: " + curfile, false); if (percent==100) InstallOutput.AddText("Done!", false); else if (percent==-1) throwerror(true, "Error during extracting files"); ProgressBar.SetValue(0, 100, percent/(1+InstallInfo.command_entries.size())); ProgressBar.Draw(); chtype input = getch(); if (input == 'c') { if (YesNoBox(GetTranslation("Install commands are still running\n" "If you abort now this may lead to a broken installation\n" "Are you sure?"))) { CleanPasswdString(passwd); passwd = NULL; EndProg(); } } } } SuHandler.SetThinkFunc(InstThinkFunc, passwd); SuHandler.SetOutputFunc(PrintInstOutput, &InstallOutput); percent = 100/(1+InstallInfo.command_entries.size()); // Convert to overall progress short step = 2; // Not 1, because extracting files is also a step for (std::list<command_entry_s*>::iterator it=InstallInfo.command_entries.begin(); it!=InstallInfo.command_entries.end(); it++, step++) { if ((*it)->command.empty()) continue; ProggWindow.Clear(); ProggWindow.AddText(""); ProggWindow.AddText(CreateText("</B/29>%s:<!29!B>", GetTranslation("Status"))); ProggWindow.AddText(CreateText("%s (%d/%d)", GetTranslation((*it)->description.c_str()), step, InstallInfo.command_entries.size()+1), true, BOTTOM, 24); ProgressBar.Draw(); std::string command = (*it)->command + " " + GetParameters(*it); InstallOutput.AddText(""); InstallOutput.AddText(CreateText("Execute: %s", command.c_str())); InstallOutput.AddText(""); InstallOutput.AddText(""); if (((*it)->need_root == NEED_ROOT) || alwaysroot) { SuHandler.SetPath((*it)->path.c_str()); SuHandler.SetCommand(command); if (!SuHandler.ExecuteCommand(passwd)) { if ((*it)->exit_on_failure) { CleanPasswdString(passwd); passwd = NULL; throwerror(true, "%s\n('%s')", GetTranslation("Failed to execute install command"), SuHandler.GetErrorMsgC()); } } } else { // Redirect stderr to stdout, so that errors will be displayed too command += " 2>&1"; setenv("PATH", (*it)->path.c_str(), 1); FILE *pipe = popen(command.c_str(), "r"); char term[1024]; if (pipe) { while (fgets(term, sizeof(term), pipe)) { InstallOutput.AddText(term); chtype input = getch(); if (input == 'c') /*injectCDKSwindow(InstallOutput.GetSWin(), input);*/ { if (YesNoBox(GetTranslation("Install commands are still running\n" "If you abort now this may lead to a broken installation\n" "Are you sure?"))) { CleanPasswdString(passwd); passwd = NULL; EndProg(); } } } // Check if command exitted normally and close pipe int state = pclose(pipe); if (!WIFEXITED(state) || (WEXITSTATUS(state) == 127)) // SH returns 127 if command execution failes { if ((*it)->exit_on_failure) { CleanPasswdString(passwd); passwd = NULL; throwerror(true, "Failed to execute install command"); } } } else { CleanPasswdString(passwd); passwd = NULL; throwerror(true, "Could not execute installation commands (could not open pipe)"); } #if 0 // Need to find a good way to safely suspend a process...this code doesn't always work :( int pipefd[2]; pipe(pipefd); pid_t pid = fork(); if (pid == -1) throwerror(true, "Error during command execution: Could not fork process"); else if (pid) // Parent process { close(pipefd[1]); // We're not going to write here std::string out; char c; int compid = -1; // PID of the executed command while(read(pipefd[0], &c, sizeof(c)) > 0) { out += c; if (c == '\n') { if (compid == -1) { compid = atoi(out.c_str()); InstallOutput.AddText(CreateText("pid: %d compid: %d", pid, compid), false); } else InstallOutput.AddText(out, false); out.clear(); } chtype input = getch(); if (input != ERR) /*injectCDKSwindow(InstallOutput.GetSWin(), input);*/ { if (kill(compid, SIGTSTP) < 0) // Pause command execution WarningBox("PID Error: %s\n", strerror(errno)); char *buttons[2] = { GetTranslation("Yes"), GetTranslation("No") }; CCharListHelper msg; msg.AddItem(GetTranslation("This will abort the installation")); msg.AddItem(GetTranslation("Are you sure?")); CCDKDialog dialog(CDKScreen, CENTER, CENTER, msg, msg.Count(), buttons, 2); dialog.SetBgColor(26); int ret = dialog.Activate(); bool cont = ((ret == 1) || (dialog.ExitType() != vNORMAL)); dialog.Destroy(); refreshCDKScreen(CDKScreen); if (!cont) { kill(pid, SIGTERM); EndProg(); } kill(compid, SIGCONT); // Continue command execution } } close (pipefd[0]); int status; //waitpid(pid, &status, 0); } else // Child process { // Redirect stdout to pipe close(STDOUT_FILENO); dup (pipefd[1]); close (pipefd[0]); // No need to read here // Make sure no errors are printed and write pid of new command command += " 2> /dev/null & echo $!"; execl("/bin/sh", "sh", "-c", command.c_str(), NULL); system(CreateText("echo %s", strerror(errno))); _exit(1); } #endif } percent += (1.0f/((float)InstallInfo.command_entries.size()+1.0f))*100.0f; ProgressBar.SetValue(0, 100, percent); } ProgressBar.SetValue(0, 100, 100); ProgressBar.Draw(); CleanPasswdString(passwd); passwd = NULL; ButtonBar.Clear(); ButtonBar.AddButton("Arrows", "Scroll install output"); ButtonBar.AddButton("Enter", (FileExists(InstallInfo.own_dir + "/config/finish")) ? "Continue" : "Finish"); // HACK ButtonBar.Draw(); WarningBox("Installation of %s complete!", InstallInfo.program_name.c_str()); InstallOutput.Activate(); return (InstallOutput.ExitType() == vNORMAL); }
CCDKScroll::CCDKScroll(CDKSCREEN *pScreen, int x, int y, int h, int w, int sbpos, char *title, char **list, int lcount, bool box, bool numbers, bool shadow) : CBaseCDKWidget(box) { m_pScroll = newCDKScroll(CDKScreen, x, y, sbpos, h, w, title, list, lcount, numbers, A_REVERSE, box, shadow); if (!m_pScroll) throwerror(false, "Could not create scroll window"); }
CCDKButtonBox::CCDKButtonBox(CDKSCREEN *pScreen, int x, int y, int h, int w, char *title, int rows, int cols, char **buttons, int count, chtype hlight, bool box, bool shadow) : CBaseCDKWidget(box) { m_pBBox = newCDKButtonbox(pScreen, x, y, h, w, title, rows, cols, buttons, count, hlight, box, shadow); if (!m_pBBox) throwerror(false, "Could not create button box"); }
bool CFileDialog::Activate() { char *buttons[] = { GetTranslation("Open directory"), GetTranslation("Select directory"), GetTranslation("Cancel") }; char label[] = "Dir: "; char curdir[1024]; ButtonBar.Push(); ButtonBar.AddButton("TAB", "Next button"); ButtonBar.AddButton("ENTER", "Activate button"); ButtonBar.AddButton("Arrows", "Navigate menu"); ButtonBar.AddButton("C", "Create directory"); ButtonBar.AddButton("A", "About"); ButtonBar.AddButton("ESC", "Cancel"); ButtonBar.Draw(); if (!getcwd(curdir, sizeof(curdir))) throwerror(true, "Could not read current directory"); if (chdir(m_szStartDir.c_str()) != 0) throwerror(true, "Could not open directory '%s'", m_szStartDir.c_str()); if (!ReadDir(m_szStartDir)) throwerror(true, "Could not read directory '%s'", m_szStartDir.c_str()); CCDKButtonBox ButtonBox(CDKScreen, CENTER, GetDefaultHeight(), 1, GetDefaultWidth(), 0, 1, 3, buttons, 3); ButtonBox.SetBgColor(5); if (!m_pCurDirWin && !m_pFileList) { m_pCurDirWin = new CCDKSWindow(CDKScreen, CENTER, getbegy(ButtonBox.GetBBox()->win)-2, 2, GetDefaultWidth()+1, NULL, 1); m_pCurDirWin->SetBgColor(5); if (!m_pFileList) { m_pFileList = new CCDKAlphaList(CDKScreen, CENTER, 2, getbegy(m_pCurDirWin->GetSWin()->win)-1, GetDefaultWidth()+1, const_cast<char*>(m_szTitle.c_str()), label, &m_DirItems[0], m_DirItems.size()); m_pFileList->SetBgColor(5); setCDKEntryPreProcess(m_pFileList->GetAList()->entryField, CreateDirCB, this); //m_pFileList->GetAList()->entryField->dispType = vVIEWONLY; // HACK: Disable backspace } setCDKAlphalistLLChar(m_pFileList->GetAList(), ACS_LTEE); setCDKAlphalistLRChar(m_pFileList->GetAList(), ACS_RTEE); setCDKLabelLLChar(m_pCurDirWin->GetSWin(), ACS_LTEE); setCDKLabelLRChar(m_pCurDirWin->GetSWin(), ACS_RTEE); setCDKButtonboxULChar(ButtonBox.GetBBox(), ACS_LTEE); setCDKButtonboxURChar(ButtonBox.GetBBox(), ACS_RTEE); } m_pFileList->Draw(); m_pCurDirWin->Draw(); ButtonBox.Draw(); m_pFileList->Bind(KEY_TAB, SwitchButtonK, ButtonBox.GetBBox()); // Pas TAB through ButtonBox m_szDestDir = m_szStartDir; UpdateCurDirText(); while(true) { // HACK: Give textbox content setCDKEntryValue(m_pFileList->GetAList()->entryField, chtype2Char(m_pFileList->GetAList()->scrollField->item[m_pFileList->GetAList()->scrollField->currentItem])); char *selection = m_pFileList->Activate(); if ((m_pFileList->ExitType() != vNORMAL) || (ButtonBox.GetCurrent() == 2)) break; if (!selection || !selection[0]) continue; if (ButtonBox.GetCurrent() == 1) { if (m_bAskWAccess && !WriteAccess(m_szDestDir)) { char *dbuttons[2] = { GetTranslation("Continue as root"), GetTranslation("Choose another directory") }; CCDKDialog Diag(CDKScreen, CENTER, CENTER, GetTranslation("You don't have write permissions for this directory.\n" "The files can be extracted as the root user,\n" "but you'll need to enter the root password for this later."), dbuttons, 2); Diag.SetBgColor(26); int sel = Diag.Activate(); Diag.Destroy(); refreshCDKScreen(CDKScreen); if (sel) continue; } break; } if (!FileExists(selection)) { if (YesNoBox(GetTranslation("Directory does not exist\nDo you want to create it?"))) { if (mkdir(selection, (S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH)) != 0) { WarningBox("%s\n%.75s\n%.75s", GetTranslation("Could not create directory"), selection, strerror(errno)); continue; } } else continue; } UpdateFileList(selection); } bool success = ((m_pFileList->ExitType() != vESCAPE_HIT) && (ButtonBox.GetCurrent() == 1)); ButtonBar.Pop(); if (m_bRestoreDir) chdir(curdir); // Return back to original directory return success; }
CCDKLabel::CCDKLabel(CDKSCREEN *pScreen, int x, int y, char **msg, int count, bool box, bool shadow) : CBaseCDKWidget(box) { m_pLabel = newCDKLabel(pScreen, x, y, msg, count, box, shadow); if (!m_pLabel) throwerror(false, "Could not create text label"); }
CCDKHistogram::CCDKHistogram(CDKSCREEN *pScreen, int x, int y, int h, int w, int orient, char *title, bool box, bool shadow) : CBaseCDKWidget(box) { m_pHistogram = newCDKHistogram(pScreen, x, y, h, w, orient, title, box, shadow); if (!m_pHistogram) throwerror(false, "Could not create histogram"); }
CCDKEntry::CCDKEntry(CDKSCREEN *pScreen, int x, int y, char *title, char *label, int fwidth, int min, int max, EDisplayType DispType, chtype fillch, chtype fieldattr, bool box, bool shadow) : CBaseCDKWidget(box) { m_pEntry = newCDKEntry(pScreen, x, y, title, label, fieldattr, fillch, DispType, fwidth, min, max, box, shadow); if (!m_pEntry) throwerror(false, "Could not create input entry"); }
CCDKSWindow::CCDKSWindow(CDKSCREEN *pScreen, int x, int y, int h, int w, char *title, int slines, bool box, bool shadow) : CBaseCDKWidget(box) { m_pSWindow = newCDKSwindow(pScreen, x, y, h, w, title, slines, box, shadow); if (!m_pSWindow) throwerror(false, "Could not create window"); }
CCDKDialog::CCDKDialog(CDKSCREEN *pScreen, int x, int y, char **message, int mcount, char **buttons, int bcount, chtype hlight, bool sep, bool box, bool shadow) : CBaseCDKWidget(box) { m_pDialog = newCDKDialog(pScreen, x, y, message, mcount, buttons, bcount, hlight, sep, box, shadow); if (!m_pDialog) throwerror(false, "Could not create dialog window"); }
CCDKAlphaList::CCDKAlphaList(CDKSCREEN *pScreen, int x, int y, int h, int w, char *title, char *label, char **list, int count, bool box, bool shadow) : CBaseCDKWidget(box) { m_pAList = newCDKAlphalist(pScreen, x, y, h, w, title, label, list, count, '_', A_BLINK, box, shadow); if (!m_pAList) throwerror(false, "Could not create alpha list"); }