Example #1
0
void DocSettings::Load(const XMLNode& node)
{
	CString strTagName = MakeCString(node.tagName);
	if (strTagName != pszTagSettings && strTagName != pszTagContent)
		return;

	if (strTagName == pszTagSettings)
	{
		node.GetIntAttribute(pszAttrStartPage, nPage);
		node.GetLongAttribute(pszAttrOffsetX, ptOffset.x);
		node.GetLongAttribute(pszAttrOffsetY, ptOffset.y);
		node.GetIntAttribute(pszAttrZoomType, nZoomType);
		node.GetDoubleAttribute(pszAttrZoom, fZoom);
		node.GetIntAttribute(pszAttrLayout, nLayout);
		node.GetIntAttribute(pszAttrDisplayMode, nDisplayMode);
		node.GetIntAttribute(pszAttrRotate, nRotate);
		node.GetIntAttribute(pszAttrOpenSidebarTab, nOpenSidebarTab);

		int nFirstPage;
		if (node.GetIntAttribute(pszAttrFirstPage, nFirstPage))
			bFirstPageAlone = (nFirstPage != 0);

		int nRightToLeft;
		if (node.GetIntAttribute(pszAttrRightToLeft, nRightToLeft))
			bRightToLeft = (nRightToLeft != 0);
	}

	pageSettings.clear();
	bookmarks.clear();

	list<XMLNode>::const_iterator it;
	for (it = node.childElements.begin(); it != node.childElements.end(); ++it)
	{
		const XMLNode& child = *it;
		if (MakeCString(child.tagName) == pszTagPageSettings)
		{
			int pageNo;
			if (!child.GetIntAttribute(pszAttrNumber, pageNo))
				continue;

			PageSettings& data = pageSettings[pageNo - 1];
			data.Load(child);
		}
		else if (MakeCString(child.tagName) == pszTagBookmarks)
		{
			list<XMLNode>::const_iterator it;
			for (it = child.childElements.begin(); it != child.childElements.end(); ++it)
			{
				const XMLNode& bmNode = *it;
				if (MakeCString(bmNode.tagName) == pszTagBookmark)
				{
					bookmarks.push_back(Bookmark());
					Bookmark& bookmark = bookmarks.back();
					bookmark.Load(bmNode);
				}
			}
		}
	}
}
void CInstaller::SetTitle(const std::string &t)
{
    int w = m_pTitle->w(), h = 0;
    int minheaderh = (m_pLogoBox) ? (m_pLogoBox->y() + m_pLogoBox->h() + HeaderSpacing()) : 50;
    fl_font(m_pTitle->labelfont(), m_pTitle->labelsize());
    fl_measure(t.c_str(), w, h);
    minheaderh = std::max(minheaderh, h);

    m_pTitle->size(m_pTitle->w(), minheaderh);
    m_pTitle->label(MakeCString(t));

    if (m_pHeaderGroup->h() != minheaderh)
    {
        // Center logo (if any)
        if (m_pLogoBox)
        {
            const int y = ((minheaderh - m_pLogoBox->h()) / 2);
            m_pLogoBox->position(m_pLogoBox->x(), y);
        }

        m_pHeaderGroup->size(m_pHeaderGroup->w(), minheaderh);
        
        m_pWizard->size(m_pWizard->w(), m_pCancelButton->y()-minheaderh-ButtonHSpacing());
    }
}
void CPipedCMD::Close(bool canthrow)
{
    if (!m_ChildPID)
        return;
    
    if (canthrow) 
        ::Close(m_iPipeFD[0]);
    else
        close(m_iPipeFD[0]);
    
    pid_t ret;
    int stat;
    do
    {
        ret = (canthrow) ? WaitPID(m_ChildPID, &stat, 0) : waitpid(m_ChildPID, &stat, 0);
    }
    while ((ret == -1) && (errno == EINTR));
    
    m_ChildPID = 0;
    
    if (canthrow)
    {
        if (!WIFEXITED(stat) || (WEXITSTATUS(stat) == 127))
            throw Exceptions::CExCommand(MakeCString(m_szCommand));
    }
}
Example #4
0
void Bookmark::Load(const XMLNode& node)
{
	if (MakeCString(node.tagName) != pszTagBookmark)
		return;

	wstring str;
	if (node.GetAttribute(pszAttrTitle, str))
		strTitle = MakeUTF8String(str);

	node.GetIntAttribute(pszAttrType, nLinkType);

	if (nLinkType == URL)
	{
		if (node.GetAttribute(pszAttrURL, str))
			strURL = MakeUTF8String(str);
	}
	else if (nLinkType == Page || nLinkType == View)
	{
		node.GetIntAttribute(pszAttrPage, nPage);
		if (nLinkType == View)
		{
			node.GetLongAttribute(pszAttrOffsetX, ptOffset.x);
			node.GetLongAttribute(pszAttrOffsetY, ptOffset.y);

			int nMargin;
			if (node.GetIntAttribute(pszAttrMargin, nMargin))
				bMargin = (nMargin != 0);
		}
	}

	list<XMLNode>::const_iterator it;
	for (it = node.childElements.begin(); it != node.childElements.end(); ++it)
	{
		const XMLNode& child = *it;
		if (MakeCString(child.tagName) == pszTagBookmark)
		{
			children.push_back(Bookmark());
			Bookmark& bookmark = children.back();
			bookmark.Load(child);
		}
	}
}
Example #5
0
void PageSettings::Load(const XMLNode& node)
{
	if (MakeCString(node.tagName) != pszTagPageSettings)
		return;

	list<XMLNode>::const_iterator it;
	for (it = node.childElements.begin(); it != node.childElements.end(); ++it)
	{
		const XMLNode& child = *it;
		if (MakeCString(child.tagName) == pszTagAnnotation)
		{
			anno.push_back(Annotation());
			Annotation& annotation = anno.back();
			annotation.Load(child);

			if (annotation.rects.empty())
				anno.pop_back();
		}
	}
}
void CLuaDirSelector::BrowseCB(Fl_Widget *w, void *p)
{
    CLuaDirSelector *dirsel = static_cast<CLuaDirSelector *>(p);
    CFLTKDirDialog dialog("~", "*", (Fl_File_Chooser::DIRECTORY | Fl_File_Chooser::CREATE),
             GetTranslation("Select a directory"));
    
    dialog.Value(MakeCString(GetFirstValidDir(dirsel->m_pDirInput->value())));
    dialog.Run();
    
    const char *dir = dialog.Value();
    if (dir && *dir)
    {
        dirsel->m_pDirInput->value(dir);
        dirsel->LuaDataChanged();
    }
}
CLuaMenu::CLuaMenu(const char *desc, const TOptions &l) : CBaseLuaWidget(desc), CBaseLuaMenu(l), m_iCurValue(-1)
{
    m_pMenu = new Fl_Hold_Browser(0, 0, 0, GroupHeight());
    m_pMenu->callback(SelectionCB, this);

    for (TOptions::const_iterator it=l.begin(); it!=l.end(); it++)
        m_pMenu->add(MakeTranslation(*it), MakeCString(*it));

    if (m_pMenu->size() > 0)
    {
        m_pMenu->value(1);
        m_iCurValue = 1;
    }

    GetGroup()->add(m_pMenu);
}
void CButtonBar::AddButton(const char *button, const char *desc)
{
    if (!m_pCurrentBarEntry) m_pCurrentBarEntry = new bar_entry_s;
    
    std::string txt = std::string(" </B/16>") + GetTranslation(button) + "<!16!B>: </B/8>" + GetTranslation(desc) + "<!8!B> ";
    const int l = strlen(button) + strlen(desc) + 4; // 4 extra chars: 3 spaces and an ':'
    if ((getmaxx(MainWin)-2) < (m_pCurrentBarEntry->iCurTextLength + l))
    {
        m_pCurrentBarEntry->Texts.push_back(MakeCString(m_pCurrentBarEntry->szCurrentText));
        m_pCurrentBarEntry->szCurrentText = txt;
        m_pCurrentBarEntry->iCurTextLength = l;
    }
    else
    {
        m_pCurrentBarEntry->szCurrentText += txt;
        m_pCurrentBarEntry->iCurTextLength += l;
    }
}
Example #9
0
void DictionaryInfo::ReadLocalizedStrings(vector<LocalizedString>& loc, const XMLNode& node)
{
	list<XMLNode>::const_iterator it;
	for (it = node.childElements.begin(); it != node.childElements.end(); ++it)
	{
		const XMLNode& child = *it;
		if (MakeCString(child.tagName) == pszTagString)
		{
			DWORD code;
			if (!child.GetHexAttribute(pszAttrLocalization, code))
				continue;

			wstring value;
			if (!child.GetAttribute(pszAttrValue, value))
				continue;

			loc.push_back(make_pair(code, MakeUTF8String(value)));
		}
	}
}
void CLuaInputField::UpdateSize()
{
    m_pPack->size(GetGroup()->w(), m_pPack->h());
    
    if (GetLabel().empty() || !m_pLabel)
    {
        m_pInputField->size(GetGroup()->w(), m_pInputField->h());
        return;
    }
    
    std::string label = GetTranslation(GetLabel());
    TSTLStrSize max = SafeConvert<TSTLStrSize>(GetLabelWidth()), length = label.length();
    
    if (length > max)
        m_pLabel->label(MakeCString(label.substr(0, max)));
    
    fl_font(m_pLabel->labelfont(), m_pLabel->labelsize());
    int w = static_cast<int>(fl_width(' ')) * GetLabelWidth();
    m_pLabel->size(w, m_pLabel->h());
    
    m_pInputField->size(GetGroup()->w() - PackSpacing() - w, m_pInputField->h());
}
CAppManager::CAppManager()
{
    const int mainw = 560, mainh = 330;
    m_pMainWindow = new Fl_Window(mainw, mainh, "Nixstaller - App Manager");

    m_pAppList = new Fl_Hold_Browser(20, 40, 180, 240, "Installed applications");
    m_pAppList->align(FL_ALIGN_TOP);
    GetRegisterEntries(&m_AppVec);
    for (std::vector<app_entry_s *>::iterator it=m_AppVec.begin(); it!=m_AppVec.end(); it++)
        m_pAppList->add(MakeCString((*it)->name));
    m_pAppList->callback(AppListCB, this);
    m_pAppList->value(1);

    Fl_Tabs *pTabs = new Fl_Tabs((m_pAppList->x()+m_pAppList->w())+20, 20, 300, 260);
    
    Fl_Group *pInfoTab = new Fl_Group((m_pAppList->x()+m_pAppList->w())+20, 40, 300, 260, "Info");
    m_pInfoOutput = new Fl_Help_View((m_pAppList->x()+m_pAppList->w())+20, 40, 300, 240);
    m_pInfoOutput->align(FL_ALIGN_TOP);
    pInfoTab->end();
    
    Fl_Group *pFilesTab = new Fl_Group((m_pAppList->x()+m_pAppList->w())+20, 40, 300, 260, "Files");
    m_pFilesTextDisplay = new Fl_Text_Display((m_pAppList->x()+m_pAppList->w())+20, 40, 300, 240);
    m_pFilesTextBuffer = new Fl_Text_Buffer;
    m_pFilesTextDisplay->buffer(m_pFilesTextBuffer);
    
    pFilesTab->end();
    
    pTabs->end();
    m_pUninstallButton = new Fl_Button(20, (m_pAppList->y()+m_pAppList->h())+20, 120, 25, "Uninstall");
    m_pUninstallButton->callback(UninstallCB, this);
    m_pExitButton = new Fl_Button((mainw-140), (m_pAppList->y()+m_pAppList->h())+20, 120, 25, "Exit");
    m_pExitButton->callback(ExitCB);
    
    UpdateInfo(true);

    m_pUninstallWindow = new CUninstallWindow(this);
    
    m_pMainWindow->end();
}
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);
}
Example #13
0
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;
}
Example #14
0
object call_c(int func, object proc_ad, object arg_list)
/* Call a WIN32 or Linux C function in a DLL or shared library.
   Alternatively, call a machine-code routine at a given address. */
{
    volatile unsigned long arg;  // !!!! magic var to push values on the stack
    volatile int argsize;        // !!!! number of bytes to pop

    s1_ptr arg_list_ptr, arg_size_ptr;
    object_ptr next_arg_ptr, next_size_ptr;
    object next_arg, next_size;
    int iresult, i;
    double dbl_arg, dresult;
    float flt_arg, fresult;
    unsigned long size;
    int proc_index;
    int cdecl_call;
    int (*int_proc_address)();
    unsigned return_type;
    char NameBuff[100];

    // Setup and Check for Errors

    proc_index = get_pos_int("c_proc/c_func", proc_ad);
    if ((unsigned)proc_index >= c_routine_next) {
	sprintf(TempBuff, "c_proc/c_func: bad routine number (%d)", proc_index);
	RTFatal(TempBuff);
    }

    int_proc_address = c_routine[proc_index].address;
#if defined(EWINDOWS) && !defined(EWATCOM)
    cdecl_call = c_routine[proc_index].convention;
#endif
    if (IS_ATOM(arg_list)) {
	RTFatal("c_proc/c_func: argument list must be a sequence");
    }

    arg_list_ptr = SEQ_PTR(arg_list);
    next_arg_ptr = arg_list_ptr->base + arg_list_ptr->length;

    // only look at length of arg size sequence for now
    arg_size_ptr = c_routine[proc_index].arg_size;
    next_size_ptr = arg_size_ptr->base + arg_size_ptr->length;

    return_type = c_routine[proc_index].return_size; // will be INT

    if (func && return_type == 0 || !func && return_type != 0) {
	if (c_routine[proc_index].name->length < 100)
	    MakeCString(NameBuff, MAKE_SEQ(c_routine[proc_index].name));
	else
	    NameBuff[0] = '\0';
	sprintf(TempBuff, func ? "%s does not return a value" :
				 "%s returns a value",
				 NameBuff);
	RTFatal(TempBuff);
    }

    if (arg_list_ptr->length != arg_size_ptr->length) {
	if (c_routine[proc_index].name->length < 100)
	    MakeCString(NameBuff, MAKE_SEQ(c_routine[proc_index].name));
	else
	    NameBuff[0] = '\0';
	sprintf(TempBuff, "C routine %s() needs %d argument%s, not %d",
			  NameBuff,
			  arg_size_ptr->length,
			  (arg_size_ptr->length == 1) ? "" : "s",
			  arg_list_ptr->length);
	RTFatal(TempBuff);
    }

    argsize = arg_list_ptr->length << 2;


    // Push the Arguments

    for (i = 1; i <= arg_list_ptr->length; i++) {

	next_arg = *next_arg_ptr--;
	next_size = *next_size_ptr--;

	if (IS_ATOM_INT(next_size))
	    size = INT_VAL(next_size);
	else if (IS_ATOM(next_size))
	    size = (unsigned long)DBL_PTR(next_size)->dbl;
	else
	    RTFatal("This C routine was defined using an invalid argument type");

	if (size == C_DOUBLE || size == C_FLOAT) {
	    /* push 8-byte double or 4-byte float */
	    if (IS_ATOM_INT(next_arg))
		dbl_arg = (double)next_arg;
	    else if (IS_ATOM(next_arg))
		dbl_arg = DBL_PTR(next_arg)->dbl;
	    else {
		arg = arg+argsize+9999; // 9999 = 270f hex - just a marker for asm code
		RTFatal("arguments to C routines must be atoms");
	    }

	    if (size == C_DOUBLE) {
		arg = *(1+(unsigned long *)&dbl_arg);

		push();  // push high-order half first
		argsize += 4;
		arg = *(unsigned long *)&dbl_arg;
		push(); // don't combine this with the push() below - Lcc bug
	    }
	    else {
		/* C_FLOAT */
		flt_arg = (float)dbl_arg;
		arg = *(unsigned long *)&flt_arg;
		push();
	    }
	}
	else {
	    /* push 4-byte integer */
	    if (size >= E_INTEGER) {
		if (IS_ATOM_INT(next_arg)) {
		    if (size == E_SEQUENCE)
			RTFatal("passing an integer where a sequence is required");
		}
		else {
		    if (IS_SEQUENCE(next_arg)) {
			if (size != E_SEQUENCE && size != E_OBJECT)
			    RTFatal("passing a sequence where an atom is required");
		    }
		    else {
			if (size == E_SEQUENCE)
			    RTFatal("passing an atom where a sequence is required");
		    }
		    RefDS(next_arg);
		}
		arg = next_arg;
		push();
	    }
	    else if (IS_ATOM_INT(next_arg)) {
		arg = next_arg;
		push();
	    }
	    else if (IS_ATOM(next_arg)) {
		// atoms are rounded to integers

		arg = (unsigned long)DBL_PTR(next_arg)->dbl; //correct
		// if it's a -ve f.p. number, Watcom converts it to int and
		// then to unsigned int. This is exactly what we want.
		// Works with the others too.
		push();
	    }
	    else {
		arg = arg+argsize+9999; // just a marker for asm code
		RTFatal("arguments to C routines must be atoms");
	    }
	}
    }

    // Make the Call - The C compiler thinks it's a 0-argument call

    // might be VOID C routine, but shouldn't crash

    if (return_type == C_DOUBLE) {
	// expect double to be returned from C routine
#if defined(EWINDOWS) && !defined(EWATCOM)
	if (cdecl_call) {
	    dresult = (*((double (  __cdecl *)())int_proc_address))();
	    pop();
	}
	else
#endif
	    dresult = (*((double (__stdcall *)())int_proc_address))();

#ifdef ELINUX
	pop();
#endif
	return NewDouble(dresult);
    }

    else if (return_type == C_FLOAT) {
	// expect float to be returned from C routine
#if defined(EWINDOWS) && !defined(EWATCOM)
	if (cdecl_call) {
	    fresult = (*((float (  __cdecl *)())int_proc_address))();
	    pop();
	}
	else
#endif
	    fresult = (*((float (__stdcall *)())int_proc_address))();

#ifdef ELINUX
	pop();
#endif
	return NewDouble((double)fresult);
    }

    else {
	// expect integer to be returned
#if defined(EWINDOWS) && !defined(EWATCOM)
	if (cdecl_call) {
	    iresult = (*((int (  __cdecl *)())int_proc_address))();
	    pop();
	}
	else
#endif
	    iresult = (*((int (__stdcall *)())int_proc_address))();
#ifdef ELINUX
	pop();
#endif
	if ((return_type & 0x000000FF) == 04) {
	    /* 4-byte integer - usual case */
	    // check if unsigned result is required
	    if ((return_type & C_TYPE) == 0x02000000) {
		// unsigned integer result
		if ((unsigned)iresult <= (unsigned)MAXINT) {
		    return iresult;
		}
		else
		    return NewDouble((double)(unsigned)iresult);
	    }
	    else {
		// signed integer result
		if (return_type >= E_INTEGER ||
		    (iresult >= MININT && iresult <= MAXINT)) {
		    return iresult;
		}
		else
		    return NewDouble((double)iresult);
	    }
	}
	else if (return_type == 0) {
	    return 0; /* void - procedure */
	}
	/* less common cases */
	else if (return_type == C_UCHAR) {
	    return (unsigned char)iresult;
	}
	else if (return_type == C_CHAR) {
	    return (signed char)iresult;
	}
	else if (return_type == C_USHORT) {
	    return (unsigned short)iresult;
	}
	else if (return_type == C_SHORT) {
	    return (short)iresult;
	}
	else
	    return 0; // unknown function return type
    }
}
Example #15
0
void Annotation::Load(const XMLNode& node)
{
	if (MakeCString(node.tagName) != pszTagAnnotation)
		return;

	int borderType;
	if (node.GetIntAttribute(pszAttrBorder, borderType))
	{
		if (borderType >= BorderNone && borderType <= BorderXOR)
			nBorderType = borderType;
	}

	COLORREF color;
	if (node.GetColorAttribute(pszAttrBorderColor, color))
		crBorder = color;

	int nHideBorder;
	if (node.GetIntAttribute(pszAttrBorderHideInactive, nHideBorder))
		bHideInactiveBorder = !!nHideBorder;

	int fillType;
	if (node.GetIntAttribute(pszAttrFill, fillType))
	{
		if (fillType >= FillNone && fillType <= FillXOR)
			nFillType = fillType;
	}

	if (node.GetColorAttribute(pszAttrFillColor, color))
		crFill = color;

	int nPercent;
	if (node.GetIntAttribute(pszAttrFillTransparency, nPercent))
	{
		if (nPercent >= 0 && nPercent <= 100)
			fTransparency = nPercent / 100.0;
	}

	int nHideFill;
	if (node.GetIntAttribute(pszAttrFillHideInactive, nHideFill))
		bHideInactiveFill = !!nHideFill;

	wstring str;
	if (node.GetAttribute(pszAttrComment, str))
		strComment = MakeUTF8String(str);

	int nShowComment;
	if (node.GetIntAttribute(pszAttrCommentAlwaysShow, nShowComment))
		bAlwaysShowComment = !!nShowComment;

	if (node.GetAttribute(pszAttrURL, str))
		strURL = MakeUTF8String(str);

	rects.clear();
	list<XMLNode>::const_iterator it;
	for (it = node.childElements.begin(); it != node.childElements.end(); ++it)
	{
		const XMLNode& child = *it;
		if (MakeCString(child.tagName) == pszTagRect)
		{
			GRect rect;
			if (!child.GetIntAttribute(pszAttrLeft, rect.xmin)
					|| !child.GetIntAttribute(pszAttrTop, rect.ymin)
					|| !child.GetIntAttribute(pszAttrRight, rect.xmax)
					|| !child.GetIntAttribute(pszAttrBottom, rect.ymax))
				continue;

			rects.push_back(rect);
		}
	}

	UpdateBounds();
}
Example #16
0
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);
}
Example #17
0
bool ConfParams()
{
    param_entry_s *pFirstParam = NULL;
    std::vector<char *> ParamItems;

    for (std::list<command_entry_s *>::iterator p=InstallInfo.command_entries.begin();p!=InstallInfo.command_entries.end();
         p++)
    {
        for (std::map<std::string, param_entry_s *>::iterator p2=(*p)->parameter_entries.begin();
             p2!=(*p)->parameter_entries.end();p2++)
        {
            if (!pFirstParam) pFirstParam = p2->second;
            ParamItems.push_back(MakeCString(p2->first));
        }
    }

    if (!pFirstParam) return true; // No command entries...no need for this screen
    
    char *title = CreateText("<C></B/29>%s<!29!B>", GetTranslation("Configure parameters"));
    char *buttons[3] = { GetTranslation("Edit parameter"), GetTranslation("Continue"), GetTranslation("Cancel") };
    
    ButtonBar.Clear();
    ButtonBar.AddButton("TAB", "Next button");
    ButtonBar.AddButton("ENTER", "Activate button");
    ButtonBar.AddButton("Arrows", "Navigate menu");
    ButtonBar.AddButton("A", "About");
    ButtonBar.AddButton("ESC", "Exit program");
    ButtonBar.Draw();
    
    CCDKButtonBox ButtonBox(CDKScreen, CENTER, GetDefaultHeight()-1, 1, GetDefaultWidth(), 0, 1, 3, buttons, 3);
    ButtonBox.SetBgColor(5);

    CCDKScroll ScrollList(CDKScreen, getbegx(ButtonBox.GetBBox()->win), 2, getbegy(ButtonBox.GetBBox()->win)-1,
                          GetDefaultWidth()/2, RIGHT,
                          title, &ParamItems[0], ParamItems.size());
    ScrollList.SetBgColor(5);
    ScrollList.Bind('a', ShowAboutK);

    const int defh = 3;
    
    CCDKSWindow DescWindow(CDKScreen, (getbegx(ScrollList.GetScroll()->win) + getmaxx(ScrollList.GetScroll()->win))-1, 2,
                           getmaxy(ScrollList.GetScroll()->win)-defh-1, (GetDefaultWidth()/2)+1, CreateText("<C></B/29>%s<!29!B>",
                           GetTranslation("Description")), 30);
    DescWindow.SetBgColor(5);
    DescWindow.AddText(GetTranslation(pFirstParam->description));
    
    CCDKSWindow DefWindow(CDKScreen, (getbegx(ScrollList.GetScroll()->win) + getmaxx(ScrollList.GetScroll()->win))-1,
                          getmaxy(DescWindow.GetSWin()->win), defh, (GetDefaultWidth()/2)+1, NULL, 4);
    DefWindow.SetBgColor(5);
    
    const char *str = pFirstParam->defaultval.c_str();
    if (pFirstParam->param_type == PTYPE_BOOL)
    {
        if (!strcmp(str, "true")) str = GetTranslation("Enabled");
        else str = GetTranslation("Disabled");
    }
    
    DefWindow.AddText(CreateText("</B/29>%s:<!29!B> %s", GetTranslation("Default"), str), false);
    DefWindow.AddText(CreateText("</B/29>%s:<!29!B> %s", GetTranslation("Current"), str), false);

    setCDKScrollLLChar(ScrollList.GetScroll(), ACS_LTEE);
    setCDKScrollLRChar(ScrollList.GetScroll(), ACS_BTEE);
    setCDKScrollURChar(ScrollList.GetScroll(), ACS_TTEE);
    setCDKSwindowULChar(DescWindow.GetSWin(), ACS_TTEE);
    setCDKSwindowLLChar(DescWindow.GetSWin(), ACS_LTEE);
    setCDKSwindowLRChar(DescWindow.GetSWin(), ACS_RTEE);
    setCDKSwindowURChar(DefWindow.GetSWin(), ACS_RTEE);
    setCDKSwindowLRChar(DefWindow.GetSWin(), ACS_RTEE);
    setCDKButtonboxULChar(ButtonBox.GetBBox(), ACS_LTEE);
    setCDKButtonboxURChar(ButtonBox.GetBBox(), ACS_RTEE);
    
    ButtonBox.Draw();
    DescWindow.Draw();
    DefWindow.Draw();
    
    void *Data[4] = { &DescWindow, &DefWindow, &ScrollList, &ParamItems };
    setCDKScrollPreProcess(ScrollList.GetScroll(), ScrollParamMenuK, &Data);

    ScrollList.Bind(KEY_TAB, SwitchButtonK, ButtonBox.GetBBox());
    
    bool success = false;
    while(1)
    {
        int selection = ScrollList.Activate();
    
        if (ScrollList.ExitType() == vNORMAL)
        {
            if (ButtonBox.GetCurrent() == 1)
            {
                success = true;
                break;
            }
            else if (ButtonBox.GetCurrent() == 2)
            {
                success = false;
                break;
            }
            
            param_entry_s *pParam = GetParamByName(ParamItems[selection]);
            
            if (pParam->param_type == PTYPE_DIR)
            {
                CFileDialog filedialog(GetFirstValidDir(pParam->value),
                                       CreateText("<C>%s", GetTranslation("Select a directory")),  true, false);
                if (filedialog.Activate()) pParam->value = filedialog.Result();
                filedialog.Destroy();
                refreshCDKScreen(CDKScreen);
            }
            else if (pParam->param_type == PTYPE_STRING)
            {
                CCDKEntry entry(CDKScreen, CENTER, CENTER, GetTranslation("Please enter new value"), "", 40, 0, 256);
                entry.SetBgColor(26);
                entry.SetValue(pParam->value);
                
                const char *newval = entry.Activate();
                
                if ((entry.ExitType() == vNORMAL) && newval)
                    pParam->value = newval;
                
                // Restore screen
                entry.Destroy();
                refreshCDKScreen(CDKScreen);
            }
            else
            {
                std::vector<char *> chitems;
                int cur = 0;
                
                if (pParam->param_type == PTYPE_BOOL)
                {
                    chitems.push_back(GetTranslation("Disable"));
                    chitems.push_back(GetTranslation("Enable"));
                    cur = (pParam->value == "true") ? 1 : 0;
                }
                else
                {
                    int i = 0;
                    for (std::list<std::string>::iterator it=pParam->options.begin(); it!=pParam->options.end();it++, i++)
                    {
                        chitems.push_back(GetTranslation(MakeCString(*it)));
                        if (*it == pParam->value)
                            cur = i;
                    }
                }
                
                CCDKScroll chScrollList(CDKScreen, CENTER, CENTER, 6, 30, RIGHT,
                                        GetTranslation("Please choose new value"), &chitems[0], chitems.size());
                chScrollList.SetBgColor(26);
                chScrollList.SetCurrent(cur);
                
                int chsel = chScrollList.Activate();
                
                if (chScrollList.ExitType() == vNORMAL)
                {
                    if (pParam->param_type == PTYPE_BOOL)
                    {
                        if (!strcmp(chitems[chsel], GetTranslation("Enable"))) pParam->value = "true";
                        else pParam->value = "false";
                    }
                    else
                        pParam->value = chitems[chsel];
                }
                    
                chScrollList.Destroy();
                refreshCDKScreen(CDKScreen);
            }

            DefWindow.Clear();
            DefWindow.AddText(CreateText("</B/29>%s:<!29!B> %s", GetTranslation("Default"), GetParamDefault(pParam)),
                              false);
            DefWindow.AddText(CreateText("</B/29>%s:<!29!B> %s", GetTranslation("Current"), GetParamValue(pParam)),
                              false);
        }
        else
        {
            success = false;
            break;
        }
    }
    
    return success;
}