⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 zhcon.cpp

📁 zhcon最新版本0.2.4
💻 CPP
📖 第 1 页 / 共 2 页
字号:
// vi:ts=4:shiftwidth=4:expandtab/***************************************************************************                          zhcon.cpp  -  description                             -------------------    begin                : Fri Mar 23 2001    copyright            : (C) 2001 by ejoy    email                : ejoy@users.sourceforge.net ***************************************************************************//*************************************************************************** *                                                                         * *   This program is free software; you can redistribute it and/or modify  * *   it under the terms of the GNU General Public License as published by  * *   the Free Software Foundation; either version 2 of the License, or     * *   (at your option) any later version.                                   * *                                                                         * ***************************************************************************/#ifdef HAVE_CONFIG_H#include <config.h>#endif#include <iostream>#include <strstream>#include <unistd.h>#include <cstdlib>#include <cstdio>#include <sys/ioctl.h>#if defined(linux)    #include <linux/limits.h>    #include <linux/kd.h>    #include <linux/vt.h>    #include <pty.h>#elif defined(__FreeBSD__)    #include <termios.h>    //#include <machine/console.h>    #include <sys/consio.h>    #include <libutil.h>    #define TCSETA TIOCSETA#endif#include <sys/types.h>#include <sys/stat.h>#include <fcntl.h>#include <signal.h>#include <pwd.h>#include <stdexcept>#include <algorithm>#include <locale.h>#include "global.h"#include "console.h"#include "inputclient.h"#include "inputmanager.h"#include "nativeinputserver.h"#ifdef HAVE_UNICON_LIB    #include "uniconinputserver.h"#endif// for termcap, must include after gpm.h, why?#include <term.h>#include "gbkdecoder.h"#include "gbdecoder.h"#include "big5decoder.h"#include "gb2big5decoder.h"#include "big52gbdecoder.h"#include "jisdecoder.h"#include "kscdecoder.h"#include "configfile.h"//#include "fade.h"#include "zhcon.h"#include "basefont.h"//#include "popwin.h"BaseFont* gpHzFont;BaseFont* gpAscFont;#ifndef NDEBUG#include "debug.h"ofstream debug("debug");#endifZhcon* Zhcon::mpZhcon = NULL;int Zhcon::mTtyPid = 0;Zhcon::STATE Zhcon::mState = STOP;char* Zhcon::mpTips[] = {gettext_noop("Please visit zhcon.gnuchina.org for more information."),gettext_noop("Zhcon supports GB2312,GBK,BIG5,JIS,KSC encode."),gettext_noop("You can use CTRL-ALT-0 to toggle prompt bar."),gettext_noop("Press CTRL-ALT-H for online help."),gettext_noop("Zhcon supports 12,14,16,24 pixel fonts,you can change in zhcon.conf"),gettext_noop("You can use 24 pixel font on 17 monitor to get better visual effect."),gettext_noop("Hit CTRL-D to quit zhcon."),gettext_noop("You can find user manual in doc/."),gettext_noop("Zhcon can use input methods from Unicon[TurboLinux],read manual for detail."),gettext_noop("Zhcon is optimized for running under Linux FrameBuffer."),gettext_noop("Start from version 0.2.1,zhcon support gpm mouse in console."),gettext_noop("Press CTRL-F7 to change input style")};void Zhcon::SignalVtLeave(int signo) {    if(Zhcon::mpZhcon != NULL) mpZhcon->VtDoLeave();}void Zhcon::SignalVtEnter(int signo) {    if(Zhcon::mpZhcon != NULL) mpZhcon->VtDoEnter();}Zhcon::Zhcon(int argc, char* argv[]):mpCon(NULL),mpInputManager(NULL),mShowTips(true),mArgc(argc),mArgv(argv){    Zhcon::mpZhcon = this;    mConFd = mTtyFd = -1;    random_shuffle(mpTips,mpTips + sizeof(mpTips)/sizeof(char*) );}Zhcon::~Zhcon() {    CleanUp();    Zhcon::mpZhcon = NULL;}void Zhcon::Init() {    //reading config file    string cfgfile = getenv("HOME");    cfgfile += "/.zhconrc";    if (access(cfgfile.c_str(), R_OK) != 0)        cfgfile = "/etc/zhcon.conf";    //for debug,a pause enable us to attach zhcon's pid in gdb    //char c;cin>>c;    ConfigFile f(cfgfile.c_str());    //the InitXXX sequence is important,do not change    //unless you know what you are doing    InitTty();    // set blank line height, must before init font    InitGraphDev(f);    GraphMode();	seteuid(getuid());    InitLocale(f); // include init font    InitCon(f);    InitMisc(f);    VtSignalLeave();    InstallSignal();    ForkPty();    // if setlocale run before forkpty, it cause FreeBSD hang    SetEncode(mDefaultEncode, mDefaultEncode);    InitInputManager(f);    if (f.GetOption("startupmsg",true))        StartupMsg();}void Zhcon::Run() {    InputEvt evt;    Encode e;    int t = 0;//    fadeout();//    fadein();    mState = RUNNING;    while (mState == RUNNING) {        mpCon->CursorBlink();        mpInputManager->Process(evt);        if (evt.oper != InputEvt::Nothing) {            DoInputEvt(evt);            continue;        }        if (++t < 10 || mAutoEncode == MANUAL)            continue;                    t = 0;        e = mpCon->DetectBufferEncode();        switch (e) {            case ASCII:                SetEncode(mDefaultEncode, mDefaultEncode);                break;            case GB2312:                SetEncode(GB2312,                          mAutoEncode ==                          AUTO_BIG5 ? BIG5 : GB2312);                break;            case BIG5:                SetEncode(BIG5,                          mAutoEncode ==                          AUTO_GB ? GB2312 : BIG5);                break;            default:               assert(!"Wrong encode!");        }    } //while}void Zhcon::DoInputEvt(InputEvt &evt) {    switch (evt.oper) {        case InputEvt::SetEnco:            switch (evt.sub) {                case 1:                    SetEncode(GB2312, GB2312);                    break;                case 2:                    SetEncode(GBK, GBK);                    break;                case 3:                    SetEncode(BIG5, BIG5);                    break;                case 4:                    SetEncode(JIS, JIS);                    break;                case 5:                    SetEncode(KSC, KSC);                    break;                default:                    break;            }            break;        case InputEvt::AutoEncoSwitch:            switch (mAutoEncode) {                case AUTO:                    mAutoEncode = AUTO_GB;                    break;                case AUTO_GB:                    mAutoEncode = AUTO_BIG5;                    break;                case AUTO_BIG5:                    mAutoEncode = MANUAL;                    break;                case MANUAL:                    mAutoEncode = AUTO;                    break;            }            mpInputManager->Redraw();            Beep();            break;        default:            break;    }}//fork a new pty to run user's shell//return true if successfully forkvoid Zhcon::ForkPty() {    char name[50];    mTtyPid = forkpty(&mTtyFd, name, NULL, NULL);    if (mTtyPid == -1)        throw runtime_error("forkpty fail!");    ioctl(0, TIOCSCTTY, 0);    if (mTtyPid == 0) {        //child        struct passwd *userpd;        if ((userpd = getpwuid(getuid())) == NULL)            throw runtime_error("can not get user's shell!");        /* close all opened file */#ifndef OPEN_MAX    #warning OPEN_MAX undefined so far,try define it to 64    #define OPEN_MAX 64#endif        for (int i = 3; i < OPEN_MAX; i++)            close(i);        setsid();        //seteuid(getuid());   /* for security */        //TODO: handle error condition        if (mArgc > 1)            execvp(mArgv[1], &mArgv[1]);        else            execlp(userpd->pw_shell, userpd->pw_shell, (char *) 0);        exit(-1);    }}void Zhcon::InstallSignal() {    struct sigaction act;    act.sa_handler = SignalHandle;    act.sa_flags = 0;    sigemptyset(&act.sa_mask);    sigaction(SIGHUP, &act, NULL);    sigaction(SIGINT, &act, NULL);    sigaction(SIGQUIT, &act, NULL);    sigaction(SIGILL, &act, NULL);    sigaction(SIGABRT, &act, NULL);    sigaction(SIGIOT, &act, NULL);    sigaction(SIGBUS, &act, NULL);    sigaction(SIGFPE, &act, NULL);    sigaction(SIGTERM, &act, NULL);    act.sa_handler = &SignalChild;    sigemptyset(&act.sa_mask);    act.sa_flags = 0;    sigaction(SIGCHLD, &act, NULL);    //    act.sa_handler = &SignalAlarm;    //    sigemptyset(&act.sa_mask);    //    act.sa_flags = 0;    //    sigaction(SIGALRM, &act, NULL);}//do some clean up before quitvoid Zhcon::CleanUp() {    struct sigaction act;    /* done in procress and block all serious signal to prevent interrupt */    act.sa_handler = SIG_IGN;    act.sa_flags = 0;    sigemptyset(&act.sa_mask);    sigaction(SIGHUP, &act, NULL);    sigaction(SIGINT, &act, NULL);    sigaction(SIGQUIT, &act, NULL);    sigaction(SIGILL, &act, NULL);    sigaction(SIGABRT, &act, NULL);    sigaction(SIGIOT, &act, NULL);    sigaction(SIGBUS, &act, NULL);    sigaction(SIGFPE, &act, NULL);    VtSignalClean();#if defined(__FreeBSD__)    ioctl(0, VT_RELDISP, 1);#endif    GraphDev::Close();    delete gpAscFont;    delete gpHzFont;    delete gpDecoder;    delete mpCon;    delete mpInputManager;    if (mConFd != -1) {        // need restore signal ?        tcsetattr(mConFd, TCSAFLUSH, &mOldTermios);        // restore console blanking#if defined(linux)        write(mConFd, "\033[9;10]",7);  // default 10 minutes#elif defined(__FreeBSD__)         int BlankTime = 5;  // default 5 minutes        ioctl(mConFd, CONS_BLANKTIME, &BlankTime);#endif        ioctl(mConFd, KDSETMODE, KD_TEXT);  // special for vga        ioctl(mConFd, TIOCSWINSZ, &mOldWinSize);        // for mouse, keep text mode clean        // write(mConFd, "\n", 1);        // make visible cursor, use termcap "ve" instead        //write(mConFd, "\E[?25h\E[?0c", 11);        if (mpCapCursorOn) write(mConFd, mpCapCursorOn, strlen(mpCapCursorOn));        close(mConFd);    }    setenv("LC_ALL", mOldLocale.c_str(), 1);}char  Zhcon::mCapBuf[512] = {0};char* Zhcon::mpCapClearScr = NULL;char* Zhcon::mpCapCursorOff = NULL;char* Zhcon::mpCapCursorOn = NULL;void Zhcon::InitTty() {    // Using throw cause core dump when call destruct    if (!isatty(fileno(stdout))) {        printf("This is an interactive api, don't redirect stdout.\r\n");        exit(1);    }    char *TtyName = ttyname(fileno(stdout));    if (!TtyName) {        printf("Can not get current tty name.\r\n");        exit(1);    }        if (!(strncmp("/dev/tty", TtyName, 8) == 0 ||        strncmp("/dev/vc/", TtyName, 8) == 0)) {        printf("%s is not real tty or vc. Please exit current tty and try again.\r\n", TtyName);        exit(1);    }        mConFd = open(TtyName, O_RDWR);    if (mConFd == -1)        throw runtime_error("Can not open console!");    if (tcgetattr(mConFd, &mOldTermios) < 0)        throw runtime_error("Can't get console termios.");    struct termios t;    t = mOldTermios;    t.c_lflag &= ~(ECHO | ICANON | IEXTEN | ISIG | NOFLSH);    t.c_iflag &= ~(BRKINT | ICRNL | ISTRIP | IXON);    t.c_cflag &= ~(CSIZE | PARENB);    t.c_cflag |= CS8;    t.c_oflag &= ~(OPOST);    t.c_cc[VMIN] = 1;    t.c_cc[VTIME] = 0;#if defined(linux)    t.c_line = 0;#elif defined(__FreeBSD__)    t.c_cc[VDISCARD] = _POSIX_VDISABLE;    t.c_cc[VLNEXT] = _POSIX_VDISABLE;    t.c_cc[VSTART] = _POSIX_VDISABLE;    t.c_cc[VSTOP] = _POSIX_VDISABLE;    t.c_cc[VINTR] = _POSIX_VDISABLE;    t.c_cc[VSUSP] = _POSIX_VDISABLE;    t.c_cc[VDSUSP] = _POSIX_VDISABLE;    t.c_cc[VQUIT] = _POSIX_VDISABLE;    setenv("TERM","linux",1);#endif    if (tcsetattr(mConFd, TCSAFLUSH, &t) < 0)

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -