📄 console.cpp
字号:
//scroll into history buffer and switch to history mode if necessaryvoid Console::ScrollDelta(ScrollFlag f) { SelClear(); static int sBackOffset = 0; if (!mHistMode) { //history mode will be closed in PutChar() sBackOffset = 0; mHistMode = true; //save screen buffer memcpy(mpSavTextBuf, mpText, mConMaxCols * mConMaxRows); memcpy(mpSavAttrBuf, mpAttr, mConMaxCols * mConMaxRows); memcpy(mpSavFlagBuf, mpFlag, mConMaxCols * mConMaxRows); } switch (f) { case PAGE_UP: sBackOffset += mConMaxRows / 2; break; case PAGE_DOWN: sBackOffset -= mConMaxRows / 2; break; case LINE_UP: sBackOffset++; break; case LINE_DOWN: sBackOffset--; break; } if (sBackOffset >= HISTORY_LINES) sBackOffset = HISTORY_LINES - 1; if (sBackOffset < 0) sBackOffset = 0; ShowHistory(sBackOffset);}void Console::ShowHistory(int offset) { int row, indexCol, histrow; // draw history row for (row = 0; row < mConMaxRows && offset; row++, offset--) { histrow = mHistCurRow - offset; if (histrow < 0) histrow += HISTORY_LINES; indexCol = Index(0, histrow); //copy one row from history buffer memcpy(mpText + Index(0, row),mpHistText + indexCol,mConMaxCols); memcpy(mpAttr + Index(0, row),mpHistAttr + indexCol,mConMaxCols); memcpy(mpFlag + Index(0, row),mpHistFlag + indexCol,mConMaxCols); ResetFlagRow(mpText + row * mConMaxCols,mpFlag + row * mConMaxCols,mConMaxCols); } //remain rows copied from screen buffer for (int r = 0; row < mConMaxRows; row++, r++) { memcpy(mpText + Index(0, row), mpSavTextBuf + Index(0, r),mConMaxCols); memcpy(mpAttr + Index(0, row), mpSavAttrBuf + Index(0, r),mConMaxCols); memcpy(mpFlag + Index(0, row), mpSavFlagBuf + Index(0, r),mConMaxCols); ResetFlagRow(mpText + row * mConMaxCols,mpFlag + row * mConMaxCols,mConMaxCols);// DrawRow(row, &mpText[indexCol], &mpAttr[indexCol],// &mpFlag[indexCol], true); } // turn off cursor for rapid display bool isCursorOn = CursorOnOff(); if (isCursorOn) CursorHide(); Redraw(); if (isCursorOn) CursorShow();}//modified from Yu Guanghui's auto-converter(judge.c)Encode Console::DetectBufferEncode() { char *phz; int c_gb = 0; int c_big5 = 0; /* first we look up "我" and "的" ,both gb and big5 * in the text. */ for (phz = mpText; phz < (mpText + mConMaxRows * mConMaxCols); phz++) { if (*phz & 0x80) { if ((*phz == 0xB5 && *(phz + 1) == 0xC4) || ((*phz == 0xCE) && *(phz + 1) == 0xD2)) { c_gb++; phz++; continue; } else if ((*phz == 0xAA && *(phz + 1) == 0xBA) || ((*phz == 0xA7) && *(phz + 1) == 0xDA)) { c_big5++; phz++; continue; } phz++; } } if (c_gb > c_big5) { return GB2312; } else if (c_gb == c_big5) { //c_gb == 0,c_big5==0 /*There is not "我" and "的" in the text *So we test the text with a 400 words table. */ //unable to detect so return ascii return ::ASCII; //j_code3(buff,count); } else { return BIG5; }}void Console::VtSizeDelta(int ColDelta, int RowDelta) { SelClear(); int NewRows, NewEndRow; NewRows = mMaxRows - RowDelta; NewEndRow = NewRows - 1; if (Row() > NewEndRow) { //CopyLines(Row(), NewEndRow, 1); Goto(Col(), NewEndRow); } if (RowDelta > 0) { //debug<<"Clear "<<NewRows<<"-"<<mConEndRow<<endl; Clear(0, NewRows, mConEndCol, mConEndRow, 0); } Redraw(); mConMaxRows = NewRows; mConEndRow = NewEndRow; mScrollEnd = mConMaxRows;}void Console::GetVtSize(int &cols, int &rows) { cols = mConMaxCols; rows = mConMaxRows;}void Console::UpdateAttr(){ mAttr = mColor; if (mUnderline) mAttr = (mAttr & 0xf0) | mUlColor; else if (mIntensity == 0) mAttr = (mAttr & 0xf0) | mHalfColor; if (mReverse) mAttr = ((mAttr) & 0x88) | ((((mAttr) >> 4) | ((mAttr) << 4)) & 0x77); if (mIntensity == 2) mAttr |= 0x08; if (mBlink) mAttr |= 0x80;}/* use complementary color to show the mouse pointer */void Console::SelPointer(const int offset) { if (mMouseIdx >= 0 && mMouseIdx < mMaxCols * mMaxRows) { mpAttr[mMouseIdx] ^= mMouseMask; mpFlag[mMouseIdx] |= txtUpdated; // Redraw(); RedrawChar(mMouseIdx % mMaxCols, mMouseIdx / mMaxCols); } if (offset < 0) { mMouseIdx = -1; return; } mMouseIdx = offset; if (mMouseIdx > mMaxCols * mMaxRows - 1) { mMouseIdx = mMaxCols * mMaxRows - 1; } mpAttr[mMouseIdx] ^= mMouseMask; mpFlag[mMouseIdx] |= txtUpdated; // Redraw(); RedrawChar(mMouseIdx % mMaxCols, mMouseIdx / mMaxCols);}/* set reverse video on characters s-e of console with selection. */void Console::SelHighlight(const int begin, const int end) { int count = end - begin + 1; char* pAttr = &mpAttr[begin]; char* pFlag = &mpFlag[begin]; char color; while (count--) { color = *pAttr; //color = ((color) & 0x11) | (((color) & 0xe0) >> 4) | (((color) & 0x0e) << 4); color = ((color) & 0x88) | (((color) & 0x70) >> 4) | (((color) & 0x07) << 4); *pAttr = color; pAttr++; (*pFlag) |= txtUpdated; pFlag++; } // turn off cursor for rapid display bool isCursorOn = CursorOnOff(); if (isCursorOn) CursorHide(); Redraw(); if (isCursorOn) CursorShow(); /* int count = end - beign + 2; unsigned short *p; count /= 2; p = screenpos(currcons, beign, viewed); u16 *q = p; int cnt = count; if (!can_do_color) { while (cnt--) *q++ ^= 0x0800; } else if (hi_font_mask == 0x100) { while (cnt--) { u16 a = *q; a = ((a) & 0x11ff) | (((a) & 0xe000) >> 4) | (((a) & 0x0e00) << 4); *q++ = a; } } else { while (cnt--) { u16 a = *q; a = ((a) & 0x88ff) | (((a) & 0x7000) >> 4) | (((a) & 0x0700) << 4); *q++ = a; } } if (DO_UPDATE) do_update_region(currcons, (unsigned long) p, count); */}/* remove the current selection highlight, if any, from the console holding the selection. */void Console::SelClear() { SelPointer(-1); /* hide the pointer */ if (mSelStart != -1) { SelHighlight(mSelStart, mSelEnd); mSelStart = -1; }}// User settable table: what characters are to be considered alphabetic?// 256 bits__u32 Console::mInWordLut[8] = { 0x00000000, // control chars 0x03FF0000, // digits 0x87FFFFFE, // uppercase and '_' 0x07FFFFFE, // lowercase 0x00000000, 0x00000000, 0xFF7FFFFF, // latin-1 accented letters, not multiplication sign 0xFF7FFFFF // latin-1 accented letters, not division sign};int Console::InWord(const unsigned char c) { return ( mInWordLut[c>>5] >> (c & 0x1F) ) & 1;}// does screen address p correspond to character at LH/RH edge of screen?int Console::AtColEdge(const int p){ return (!(p % mMaxCols) || !((p + 1) % mMaxCols));}// Don't take this from <ctype.h>: 011-015 on the screen aren't spaces#define IS_SPACE(c) ((c) == ' ')#define IS_ASCII(c) ((c) & txtASCII)// based on kernel, linux/drivers/char/selection.cvoid Console::SelCopy(int c1, int r1, int c2, int r2, int mode) { int xs, ys, xe, ye, ps, pe; xs = CorrectCol(c1); ys = CorrectRow(r1); xe = CorrectCol(c2); ye = CorrectRow(r2); ps = ys * mMaxCols + xs; pe = ye * mMaxCols + xe; //debug<<"Mouse " <<xs<<","<<ys<<" "<<xe<<","<<ye<<" " // <<ps<<","<<pe<<" "<<endl; if (mode == 4) { // useful for screendump without selection highlights SelClear(); return; } if (ps > pe) // make exchange if sel_start > sel_end { int tmp = ps; ps = pe; pe = tmp; } int new_sel_start, new_sel_end; bool spc, ascii; char *bp, *obp; int i; switch (mode) { case 0: // character-by-character selection new_sel_start = ps; new_sel_end = pe; break; case 1: // word-by-word selection spc = IS_SPACE(mpText[ps]); ascii = IS_ASCII(mpFlag[ps]); for (new_sel_start = ps; ; ps--) { if (ascii) { if (spc && !IS_SPACE(mpText[ps])) break; if (!spc && !InWord(mpText[ps])) break; } else { if (IS_ASCII(mpFlag[ps])) break; } new_sel_start = ps; if (!(ps % mMaxCols)) break; } spc = IS_SPACE(mpText[pe]); ascii = IS_ASCII(mpFlag[pe]); for (new_sel_end = pe; ; pe++) { if (ascii) { if (spc && !IS_SPACE(mpText[pe])) break; if (!spc && !InWord(mpText[pe])) break; } else { if (IS_ASCII(mpFlag[pe])) break; } new_sel_end = pe; if (!((pe+1) % mMaxCols)) break; } break; case 2: // line-by-line selection new_sel_start = ps - ps % mMaxCols; new_sel_end = pe + mMaxCols - pe % mMaxCols - 1; break; case 3: SelPointer(pe); return; default: return; } // remove the pointer SelPointer(-1); // select to end of line if on trailing space if (new_sel_end > new_sel_start && !AtColEdge(new_sel_end) && IS_SPACE(mpText[new_sel_end])) { for (pe = new_sel_end + 1; ; pe++) if (!IS_SPACE(mpText[pe]) || AtColEdge(pe)) break; if (IS_SPACE(mpText[pe])) new_sel_end = pe; } if (mSelStart == -1) // no current selection SelHighlight(new_sel_start, new_sel_end); else if (new_sel_start == mSelStart) { if (new_sel_end == mSelEnd) // no action required return; else if (new_sel_end > mSelEnd) // extend to right SelHighlight(mSelEnd + 1, new_sel_end); else // contract from right SelHighlight(new_sel_end + 1, mSelEnd); } else if (new_sel_end == mSelEnd) { if (new_sel_start < mSelStart) // extend to left SelHighlight(new_sel_start, mSelStart - 1); else // contract from left SelHighlight(mSelStart, new_sel_start - 1); } else // some other case; start selection from scratch { SelClear(); SelHighlight(new_sel_start, new_sel_end); } mSelStart = new_sel_start; mSelEnd = new_sel_end; // Allocate a new buffer before freeing the old one ... bp = new char[mSelEnd-mSelStart+1]; if (!bp) { // selection: kmalloc() failed SelClear(); return; } if (mpSelBuf) delete[] mpSelBuf; mpSelBuf = bp; obp = bp; for (i = mSelStart; i <= mSelEnd; i++) { *bp = mpText[i]; if (!IS_SPACE(*bp++)) obp = bp; if (! ((i + 1) % mMaxCols)) { // strip trailing blanks from line and add newline, // unless non-space at end of line. if (obp != bp) { bp = obp; *bp++ = '\r'; } obp = bp; } } mSelBufLen = bp - mpSelBuf;}void Console::SelPaste(int fd) { assert(fd >= 0); int pasted = 0, count; while (mpSelBuf && (mSelBufLen > pasted)) { count = mSelBufLen - pasted; pasted = write(fd, mpSelBuf, count); pasted += count; }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -