📄 term.c
字号:
*/
termTryScroll(-term.winSize.cy / 2);
else
emulFuncKeyPress(emulGetTerm()->keyPageUp);
break;
case VK_NEXT:
if (shiftPressed)
/* Shift-PageDown acts like xterm - scroll forwards in
* history half a terminal height
*/
termTryScroll(term.winSize.cy / 2);
else
emulFuncKeyPress(emulGetTerm()->keyPageDown);
break;
case VK_UP:
emulFuncKeyPress((term.ansiCursorKeys ? "\x1bOA" : "\x1b[A"));
break;
case VK_DOWN:
emulFuncKeyPress((term.ansiCursorKeys ? "\x1bOB" : "\x1b[B"));
break;
case VK_RIGHT:
emulFuncKeyPress2(EFK_LOCAL_RIGHT,
(term.ansiCursorKeys ? "\x1bOC" : "\x1b[C"));
break;
case VK_LEFT:
emulFuncKeyPress2(EFK_LOCAL_LEFT,
(term.ansiCursorKeys ? "\x1bOD" : "\x1b[D"));
break;
case VK_HOME:
emulFuncKeyPress2(EFK_LOCAL_HOME, emulGetTerm()->keyHome);
break;
case VK_END:
emulFuncKeyPress2(EFK_LOCAL_END, emulGetTerm()->keyEnd);
break;
case VK_INSERT:
if (shiftPressed)
/* Shift-Insert pastes the selection
*/
termSelectPaste();
else if (controlPressed)
/* Control-Insert copies the selection
*/
termSelectCopy();
else
emulFuncKeyPress2(EFK_LOCAL_INSERT, emulGetTerm()->keyInsert);
break;
case VK_DELETE:
emulFuncKeyPress2(EFK_LOCAL_DELETE, emulGetTerm()->keyDelete);
break;
case VK_F1:
termFuncKeyDown(shiftPressed, 1) ;
break;
case VK_F2:
termFuncKeyDown(shiftPressed, 2) ;
break;
case VK_F3:
termFuncKeyDown(shiftPressed, 3) ;
break;
case VK_F4:
termFuncKeyDown(shiftPressed, 4) ;
break;
case VK_F5:
termFuncKeyDown(shiftPressed, 5) ;
break;
case VK_F6:
termFuncKeyDown(shiftPressed, 6) ;
break;
case VK_F7:
termFuncKeyDown(shiftPressed, 7) ;
break;
case VK_F8:
termFuncKeyDown(shiftPressed, 8) ;
break;
case VK_F9:
termFuncKeyDown(shiftPressed, 9) ;
break;
case VK_F10:
termFuncKeyDown(shiftPressed, 10) ;
break;
case VK_F11:
termFuncKeyDown(shiftPressed, 11) ;
break;
case VK_F12:
termFuncKeyDown(shiftPressed, 12) ;
break;
}
}
/* User pressed a function key (F1-F12)
*
* Args:
* shiftPressed - is pressed the shift key ?
* nFkey - number of the function key
*/
void termFuncKeyDown(BOOL shiftPressed, int nFkey)
{
Emul *emul;
emul = emulGetTerm();
if (shiftPressed) {
nFkey += 10; /* Dirty hard-code by Lorinczy Zsigmond */
}
if (nFkey <= emul->nMaxFkey) {
emulFuncKeyPress(emul->keyF[nFkey-1]);
}
}
/* User pressed a normal character key
*
* Args:
* key - key that was pressed
* flags - key data from Windows message
*/
void termKeyPress(UINT key, DWORD flags)
{
/* Get state of Shift and Control keys when message was sent
*/
BOOL controlPressed = (GetKeyState(VK_CONTROL) & KF_UP) != 0;
BOOL shiftPressed = (GetKeyState(VK_SHIFT) & KF_UP) != 0;
BOOL isRepeat = (HIWORD(flags) & KF_REPEAT) != 0;
if (!term.autoRepeat && isRepeat)
return;
if (key == '\t') {
if (shiftPressed)
/* Cannot rely on Windows for Shift+Tab since it passes
* Shift+Tab as Tab.
*/
emulFuncKeyPress(emulGetTerm()->keyBacktab);
else
emulKeyPress('\t');
} else if (controlPressed && key == ' ') {
/* Cannot rely on Windows for Ctrl+Key since it passes
* Ctrl-Space as Space. Not good for Emacs, it expects
* nul.
*/
emulKeyPress(0);
} else if (key == '\b') {
if ((GetKeyState('H') & KF_UP) != 0)
emulFuncKeyPress2(EFK_LOCAL_BACKSPACE, "\b");
else if (connectGetBs2DelOption())
emulFuncKeyPress2(EFK_LOCAL_BACKSPACE,
emulGetTerm()->keyAltBackSpace);
else
emulFuncKeyPress2(EFK_LOCAL_BACKSPACE,
emulGetTerm()->keyBackSpace);
} else if (key == '\r') {
emulFuncKeyPress2 (EFK_LOCAL_SEND, "\r");
} else if (key == '\n') {
emulFuncKeyPress2 (EFK_LOCAL_SKIP, "\n");
} else {
emulKeyPress((char)key);
}
}
/* User pressed a system key (Alt+Key)
*
* Args:
* key - the key pressed
* flags - key data from Windows message
*/
void termSysKeyDown(UINT key, DWORD flags)
{
BOOL isRepeat = (HIWORD(flags) & KF_REPEAT) != 0;
int key1, key2;
char str [16], *stp;
if (!term.autoRepeat && isRepeat)
return;
if (key == VK_MENU || key == VK_SHIFT) {
return; /* LZs, 2000.10.20 --- should be tested */
}
if (key == VK_F10) {
/* When the user presses F10, Windows sends the event as a
* system key - I am glad that Windows makes this stuff *so*
* easy.
*/
/* emulFuncKeyPress((unsigned char *)emulGetTerm()->keyF10); */
termKeyDown (key, flags); /* Lorinczy Zsigmond, 2000.10.20 */
} else {
/* Windows has sent us a virtual key code - we have to
* translate that to an ASCII character.
*
* Check these functions out in the manual. Ahhh... I love
* Windows.
*/
unsigned char state[256];
#ifdef WIN32
WORD xlat[2];
#else
DWORD xlat[2];
#endif
int xlatResult;
GetKeyboardState(state);
state[VK_MENU] &= 0x7f;
xlat[0] = xlat[1] = 0;
xlatResult = ToAscii(key, (UINT)((flags >> 16) & 0xff), state, xlat, 0);
if (xlatResult == 0) { /* LZS 2000.06.20 --- I'm not sure ... */
emulKeyPress ('\x1b');
termKeyDown (key, flags);
return;
}
key1 = (BYTE)xlat[0];
key2 = (BYTE)xlat[1];
stp = str;
if (xlatResult>=1 &&
((key1 >= ' ' && key1 <= '~') || key1 == 0x0d)) {
*stp++ = 0x1b;
*stp++ = (char)key1;
}
if (xlatResult>=2 && key1 != key2 &&
((key2 >= ' ' && key2 <= '~') || key2 == 0x0d)) {
*stp++ = 0x1b;
*stp++ = (char)key2;
}
if (stp != str) {
*stp = 0;
emulFuncKeyPress(str);
}
}
}
/* Process a file drag-dropped onto the terminal
*/
void termAcceptDrag(WPARAM wparam)
{
static char droppedFileName[_MAX_PATH + 1];
char fbuffer[4096];
FILE* f;
if (socketConnected())
{
/* To maintain predictability, we only handle 1 file at a time */
if (DragQueryFile((HDROP) wparam, (UINT)-1, (LPSTR) NULL, 0)==1)
{
DragQueryFile((HDROP) wparam, 0, droppedFileName, sizeof(droppedFileName));
/* got filename, paste text from file's content */
f = fopen(droppedFileName,"r");
fgets (fbuffer, sizeof(fbuffer), f);
while (!feof(f)){
socketWrite(fbuffer, strlen(fbuffer));
fgets (fbuffer, sizeof(fbuffer), f);
}
fclose(f);
}
else
{
/* Warn user */
MessageBox(termGetWnd(), "Multiple drop unsupported", "DTelnet",
MB_APPLMODAL | MB_ICONINFORMATION);
}
}
else
{
/* Punish user */
MessageBox(termGetWnd(), "Not connected to host", "DTelnet",
MB_APPLMODAL | MB_ICONHAND);
}
DragFinish((HDROP) wparam);
}
/* Hide the caret in the terminal window
*/
void termHideCaret(void)
{
HideCaret(termWnd);
}
/* Show the caret in the terminal window
*/
void termShowCaret(void)
{
ShowCaret(termWnd);
}
/* Set the caret visibility in the terminal window
*
* Args:
* visible - should the caret be visible?
*/
void termSetCursorMode(BOOL visible)
{
if (haveCaret && visible != term.cursorVisible) {
/* We have the caret and the visibility status has changed
*/
if (visible)
ShowCaret(termWnd);
else
HideCaret(termWnd);
}
term.cursorVisible = visible;
}
/* Application has just gained focus
*/
void termSetFocus(void)
{
/* Rebuild our caret and restore its position
*/
CreateCaret(termWnd, term.caretBitmap, term.cursorRect.right, term.cursorRect.bottom);
SetCaretPos(
term.cursor.x * term.charSize.cx + term.cursorRect.left,
winTerminalToWindow(term.cursor.y) * term.charSize.cy + term.cursorRect.top
);
/* Display the caret is necessary
*/
if (term.cursorVisible)
ShowCaret(termWnd);
haveCaret = TRUE;
}
/* Application has just lost focus
*/
void termKillFocus(void)
{
/* Destroy the caret
*/
DestroyCaret();
haveCaret = FALSE;
}
/* The application window has been resized - set the terminal window size
*
* Args:
* cx - pixel width of the terminal window
* cy - pixel height of the terminal window
*/
void termSetWindowSize(int cx, int cy)
{
SIZE newSize; /* new terminal size in characters */
int growLines; /* number of lines terminal grew */
RECT rect; /* build invalidate rect */
/* Get the new terminal window dimensions in characters
*/
newSize.cx = (cx - vscrollWidth) / term.charSize.cx;
newSize.cy = cy / term.charSize.cy;
if (newSize.cx == term.winSize.cx && newSize.cy == term.winSize.cy)
/* No change in dimensions - nothing to do
*/
return;
/* Calculate the number of lines that the window was grown.
* Negative values mean that the window was shrunk
*/
growLines = newSize.cy - term.winSize.cy;
/* Resize the terminal window
*/
MoveWindow(termWnd, 0, 0, cx, cy, TRUE);
if (growLines > 0) {
/* The window height has increased - we scroll the window to
* try to keep the last defined line at the bottom of the
* window. If the line array index of the bottom of the
* window is larger than term.numLinesUsed, then we must
* scroll down, limited by term.topVisibleLine.
*/
int numLines = 0; /* number of lines to scroll down */
if (winTerminalTopLine() + newSize.cy > term.numLinesUsed) {
/* The bottom of the window has grown down past the last
* defined line. We must scroll lines down if possible.
*/
numLines = newSize.cy - (term.numLinesUsed - winTerminalTopLine());
if (numLines > term.topVisibleLine)
/* We cannot scroll down more lines than exist
*/
numLines = term.topVisibleLine;
}
if (numLines > 0) {
/* Scroll lines down
*/
winUpdate();
ScrollWindow(termWnd, 0, numLines * term.charSize.cy, NULL, NULL);
term.topVisibleLine -= numLines;
term.cursor.y += numLines;
}
/* Invalidate the extra lines at the bottom of the window
*/
rect.left = 0;
rect.right = newSize.cx * term.charSize.cx;
rect.top = term.winSize.cy * term.charSize.cy;
rect.bottom = newSize.cy * term.charSize.cy;
InvalidateRect(termWnd, &rect, FALSE);
} else if (growLines < 0) {
int numLines = 0; /* number of lines to scroll up */
/* The window height has decreased - scroll the window to try
* to keep the last line at the bottom of the window. If we
* could not previously see the last line - do not bother
* scrolling.
*/
if (term.numLinesUsed <= winTerminalTopLine() + term.winSize.cy
&& term.numLinesUsed > newSize.cy) {
/* Last line was visible - and we need to scroll. Keep
* the last line at the bottom of the window.
*/
int newTopLine = term.numLinesUsed - newSize.cy;
if (newTopLine != term.topVisibleLine)
numLines = newTopLine - term.topVisibleLine;
}
if (numLines > 0) {
/* Scroll lines up
*/
winUpdate();
/* For some bizarre reason, we have to make sure that the cursor
* does not get scrolled off the window - it does not redisplay
* when we move it back on.
*/
if (numLines > term.cursor.y) {
term.cursor.y = numLines;
winCaretPos(term.cursor.x, term.cursor.y);
}
ScrollWindow(termWnd, 0, -numLines * term.charSize.cy, NULL, NULL);
term.topVisibleLine += numLines;
term.cursor.y -= numLines;
}
}
if (newSize.cx > term.winSize.cx) {
/* Invalidate the extra columns at the right edge of the window
*/
rect.left = term.winSize.cx * term.charSize.cx;
rect.right = newSize.cx * term.charSize.cx;
rect.top = 0;
rect.bottom = newSize.cy * term.charSize.cy;
InvalidateRect(termWnd, &rect, FALSE);
}
/* Now store the new terminal window size
*/
term.winSize.cx = newSize.cx;
term.winSize.cy = newSize.cy;
termCheckSizeLimits(); // Khader
/* Make sure the terminal scroll region makes sense
*/
if (term.haveRegion) {
if (term.winSize.cy < term.scrollBottom)
term.scrollBottom = term.winSize.cy;
if (term.scrollBottom <= term.scrollTop)
term.haveRegion = FALSE;
}
if (!term.haveRegion) {
term.scrollTop = 0;
term.scrollBottom = term.winSize.cy;
}
/* Tell the telnet server about the new size
*/
if (term.winSize.cx > 0 && term.winSize.cy > 0)
rawSetWindowSize(/* term.winSize.cx, term.winSize.cy */);
/* Adjust the history scrollbar
*/
winSetScrollbar();
}
/* Windows is going to change application window size. Modify the
* proposed size to enforce a character grid
*
* Args:
* winSize - the proposed size of the terminal window
*/
void termWindowPosChanging(SIZE* winSize)
{
/* Enforce grid of 1 character cell
*/
winSize->cx -= vsc
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -