📄 command.c
字号:
break; } /* continue the next loop iteration */ DBG_MSG(1, (stderr, "more data to read\n")); } else if (0 == n) { DBG_MSG(1, (stderr, "Should not happen?\n")); break; } else if (n < 0) { /* * We do not update count and buffer pointer and continue * trying read more data in the next loop iteration. */ DBG_MSG(1, (stderr, "%s\n", strerror(errno))); if ( errno == EAGAIN || errno == EIO || /* cygwin */ errno == EINVAL) /* solaris */ break; } } /* while (count) */ assert (PVTS(r, i)->cmdbuf_base <= PVTS(r, i)->cmdbuf_endp); /* check if a child died */ if (PVTS(r, i)->dead /* && errno == EIO*/) *PVTS(r, i)->cmdbuf_endp = (char) 0; else if (n < 0 && errno != EAGAIN) { assert (!PVTS(r, i)->dead); /* in case */ /* * It seems there is a signal loss if more than one children die * at almost the same moment. The result is that * rxvt_clean_cmd_page does not flag the dead value for some * dead children. Thus, the call of rxvt_cmd_getc (-1) in * rxvt_mail_loop will fall into an infinite loop on the path to * check the input from dead children since their cmd_fd are not * excluded in the select system call. * * So we introduce the following hack to fix it. If it finds * certain dead children are processed by the select system * call, it flags it as dead. */ if (PVTS(r, i)->cmd_pid == waitpid (PVTS(r, i)->cmd_pid, NULL, WNOHANG)) { DBG_MSG(1, (stderr,"signal lost on child %d\n",i)); PVTS(r, i)->dead = 1; if (r->Options2 & Opt2_holdExit) PVTS(r, i)->hold = 1; *PVTS(r, i)->cmdbuf_endp = (char) 0; /* * increase vt_died number, there is a possible race * condition here (a signal comes in) */ r->vt_died ++; } } /* highlight inactive tab if there is some input */ if ( !(r->Options2 & Opt2_hlTabOnBell) && bufsiz != count && i != ATAB(r) ) { rxvt_tabbar_highlight_tab (r, i, False); } } /* for loop */ if (-1 != page) { assert (PVTS(r, page)->cmdbuf_base <= PVTS(r, page)->cmdbuf_endp); /* Handle the cases that the child has died */ if (r->vt_died > 0 && PVTS(r, page)->dead) return *(PVTS(r, page)->cmdbuf_ptr)++; /* Handle the cases that the child has some input */ if (PVTS(r, page)->cmdbuf_ptr < PVTS(r, page)->cmdbuf_endp) return *(PVTS(r, page)->cmdbuf_ptr)++; } else { assert (AVTS(r)->cmdbuf_base <= AVTS(r)->cmdbuf_endp); /* -1 == page, try the active tab first */ if (AVTS(r)->cmdbuf_ptr < AVTS(r)->cmdbuf_endp) { *p_page = ATAB(r); return *(AVTS(r)->cmdbuf_ptr)++; } if (rxvt_find_cmd_child (r, p_page)) return *(PVTS(r, *p_page)->cmdbuf_ptr)++; }#ifdef HAVE_X11_SM_SMLIB_H /* * ICE file descriptor must be processed after we process all file * descriptors of children. Otherwise, if a child exit, * IceProcessMessages may hang and make the entire terminal * unresponsive. */ if (-1 != r->TermWin.ice_fd && FD_ISSET (r->TermWin.ice_fd, &readfds)) { rxvt_process_ice_msgs (r); }#endif#ifdef TRANSPARENT if (h->want_full_refresh) { DBG_MSG( 1, (stderr, "full refresh\n")); h->want_full_refresh = 0; /* only work for active tab */ rxvt_scr_clear(r, ATAB(r)); rxvt_scr_touch(r, ATAB(r), False); h->want_refresh = 1; }#endif /* TRANSPARENT */ if (h->want_refresh) h->refresh_type &= ~CLIPPED_REFRESH; if (h->want_refresh || h->want_clip_refresh) { DBG_MSG( 3, ( stderr, "Refreshing screen ...")); rxvt_scr_refresh(r, ATAB(r), h->refresh_type);#ifdef HAVE_SCROLLBARS rxvt_scrollbar_update(r, 1);#endif#ifdef USE_XIM rxvt_IM_send_spot (r);#endif /* USE_XIM */ } /* if (h->want_refresh) */ } /* while (1) */ /* NOTREACHED */}/*}}} *//* EXTPROTO */voidrxvt_pointer_unblank(rxvt_t* r, int page){ DBG_MSG( 1, ( stderr, "Unblanking pointer\n")); XDefineCursor(r->Xdisplay, PVTS(r, page)->vt, r->term_pointer); rxvt_recolour_cursor(r);#ifdef POINTER_BLANK if (!(r->Options & Opt_pointerBlank)) return; /* no need to do anything */ PVTS(r, page)->hidden_pointer = 0; if (r->h->pointerBlankDelay > 0) { struct timeval tp; (void)gettimeofday(&tp, NULL); r->h->lastmotion.tv_sec = tp.tv_sec; r->h->lastmotion.tv_usec = tp.tv_usec; }#endif}#ifdef POINTER_BLANK/* INTPROTO */voidrxvt_pointer_blank(rxvt_t* r, int page){ DBG_MSG(1, ( stderr, "Blanking pointer\n")); if ((r->Options & Opt_pointerBlank) && (None != r->h->blank_pointer)) { XDefineCursor(r->Xdisplay, PVTS(r, page)->vt, r->h->blank_pointer); XFlush(r->Xdisplay); PVTS(r, page)->hidden_pointer = 1; }}#endif/* INTPROTO */voidrxvt_mouse_report(rxvt_t* r, const XButtonEvent *ev){ int button_number, key_state = 0; int x, y; x = ev->x; y = ev->y; rxvt_pixel_position(r, &x, &y); if (r->h->MEvent.button == AnyButton) { button_number = 3; } else { button_number = r->h->MEvent.button - Button1; /* add 0x3D for wheel events, like xterm does */ if (button_number >= 3) button_number += (64 - 3); } if (AVTS(r)->PrivateModes & PrivMode_MouseX10) { /* * do not report ButtonRelease * no state info allowed */ key_state = 0; if (button_number == 3) return; } else { /* XTerm mouse reporting needs these values: * 4 = Shift * 8 = Meta * 16 = Control * plus will add in our own Double-Click reporting * 32 = Double Click */ key_state = ((r->h->MEvent.state & ShiftMask) ? 4 : 0) + ((r->h->MEvent.state & r->h->ModMetaMask) ? 8 : 0) + ((r->h->MEvent.state & ControlMask) ? 16 : 0);#ifdef MOUSE_REPORT_DOUBLECLICK key_state += ((r->h->MEvent.clicks > 1) ? 32 : 0);#endif }#ifdef DEBUG_MOUSEREPORT fprintf(stderr, "Mouse ["); if (key_state & 16) fputc('C', stderr); if (key_state & 4) fputc('S', stderr); if (key_state & 8) fputc('A', stderr); if (key_state & 32) fputc('2', stderr); fprintf(stderr, "]: <%d>, %d/%d\n", button_number, x + 1, y + 1);#else rxvt_tt_printf(r, ATAB(r), "\033[M%c%c%c", (32 + button_number + key_state), (32 + x + 1), (32 + y + 1));#endif}/* * Before calling rxvt_set_bg_focused, bg and ufbg are already restored to * correct state *//* INTPROTO */voidrxvt_set_bg_focused(rxvt_t* r, int page, Bool focus){ XGCValues gcvalue; /* Make sure bg and ufbg are in correct state */ assert (0 == r->ufbg_switched); if (focus) rxvt_restore_ufbg_color (r); else rxvt_switch_ufbg_color (r); gcvalue.background = r->PixColors[Color_bg];# ifdef TRANSPARENT if (!(r->Options & Opt_transparent))# endif /* TRANSPARENT */#ifdef BACKGROUND_IMAGE if (None == PVTS(r, page)->pixmap)#endif /* BACKGROUND_IMAGE */ { XSetBackground(r->Xdisplay, r->TermWin.gc, r->PixColors[Color_bg]); XSetWindowBackground(r->Xdisplay, PVTS(r, page)->vt, r->PixColors[Color_bg]); }#ifdef TRANSPARENT if (r->Options & Opt_transparent) rxvt_check_our_parents(r); else#endif /* TRANSPARENT */#ifdef BACKGROUND_IMAGE if (None != PVTS(r, page)->pixmap) { DBG_MSG (1, (stderr, "reset pixmap bg of vt %d\n", page)); XSetWindowBackgroundPixmap(r->Xdisplay, PVTS(r, page)->vt, PVTS(r, page)->pixmap); }#endif /* BACKGROUND_IMAGE */ { /* Nothing to do, avoid compile error when defined ** TRANSPARENT but not BACKGROUND_IMAGE */ } /* ** Set foreground/background color for GC. This is necessary. ** Otherwise, the old color will be used for drawing the ** following text before a color change. */ XSetForeground (r->Xdisplay, r->TermWin.gc, r->PixColors[Color_fg]); XSetBackground (r->Xdisplay, r->TermWin.gc, r->PixColors[Color_bg]); rxvt_scr_clear(r, page); rxvt_scr_touch(r, page, True);}/*** Individual X Event handlers*/#if defined(MOUSE_WHEEL) && defined(MOUSE_SLIP_WHEELING)/* INTPROTO */voidrxvt_process_keyrelease(rxvt_t* r, XKeyEvent *ev){ DBG_MSG(2, (stderr, "KeyRelease event\n")); if (!(ev->state & ControlMask)) r->h->mouse_slip_wheel_speed = 0; else { KeySym ks; ks = XKeycodeToKeysym(r->Xdisplay, ev->keycode, 0); if (ks == XK_Control_L || ks == XK_Control_R) r->h->mouse_slip_wheel_speed = 0; }}#endif#ifdef HAVE_SCROLLBARS/* INTPROTO */voidrxvt_scrollbar_dispatcher (rxvt_t* r, int page, XButtonEvent* ev){ int reportmode = 0; struct rxvt_hidden* h = r->h; if (!h->bypass_keystate) reportmode = !!(PVTS(r, page)->PrivateModes & PrivMode_mouse_report); scrollbar_setIdle(); /* * Rxvt-style scrollbar: * move up if mouse is above slider * move dn if mouse is below slider * * XTerm-style scrollbar: * Move display proportional to pointer location * pointer near top -> scroll one line * pointer near bot -> scroll full page */# ifndef NO_SCROLLBAR_REPORT if (reportmode) { /* * Mouse report disabled scrollbar: * arrow buttons - send up/down * click on scrollbar - send pageup/down */ if ( (r->scrollBar.style == R_SB_NEXT && scrollbarnext_upButton(ev->y)) || (r->scrollBar.style == R_SB_RXVT && scrollbarrxvt_upButton(ev->y)) || (r->scrollBar.style == R_SB_SGI && scrollbarsgi_upButton(ev->y)) ) { rxvt_tt_printf(r, page, "\033[A"); } else if ( (r->scrollBar.style == R_SB_NEXT && scrollbarnext_dnButton(ev->y)) || (r->scrollBar.style == R_SB_RXVT && scrollbarrxvt_dnButton(ev->y)) || (r->scrollBar.style == R_SB_SGI && scrollbarsgi_dnButton(ev->y)) ) { rxvt_tt_printf(r, page, "\033[B"); } else { switch (ev->button) { case Button2: rxvt_tt_printf(r, page, "\014"); break; case Button1: rxvt_tt_printf(r, page, "\033[6~"); break; case Button3: rxvt_tt_printf(r, page, "\033[5~"); break; } } } else# endif /* NO_SCROLLBAR_REPORT */ { int upordown = 0; if (r->scrollBar.style == R_SB_NEXT) { if (scrollbarnext_upButton(ev->y)) upordown = -1; /* up */ else if (scrollbarnext_dnButton(ev->y)) upordown = 1; /* down */ } else if (r->scrollBar.style == R_SB_RXVT) { if (scrollbarrxvt_upButton(ev->y)) upordown = -1; /* up */ else if (scrollbarrxvt_dnButton(ev->y)) upordown = 1; /* down */ } else if (r->scrollBar.style == R_SB_SGI) { if (scrollbarsgi_upButton(ev->y)) upordown = -1; /* up */ else if (scrollbarsgi_dnButton(ev->y)) upordown = 1; /* down */ } if (upordown) {#ifndef NO_SCROLLBAR_BUTTON_CONTINUAL_SCROLLING h->scroll_arrow_delay = SCROLLBAR_INITIAL_DELAY;#endif if (rxvt_scr_page(r, ATAB(r), upordown < 0?UP:DN,1)) { if (upordown < 0) scrollbar_setUp(); else scrollbar_setDn(); } } else { switch (ev->button) { case Button2: switch (h->scrollbar_align) { case R_SB_ALIGN_TOP: h->csrO = 0; break; case R_SB_ALIGN_CENTRE: h->csrO = (r->scrollBar.bot-r->scrollBar.top)/2; break; case R_SB_ALIGN_BOTTOM: h->csrO = r->scrollBar.bot - r->scrollBar.top; break; } if ( r->scrollBar.style == R_SB_XTERM || scrollbar_above_slider(ev->y) || scrollbar_below_slider(ev->y) ) { rxvt_scr_move_to(r, page, scrollbar_position(ev->y) - h->csrO, scrollbar_size()); } scrollbar_setMotion(); break; case Button1: if (h->scrollbar_align == R_SB_ALIGN_CENTRE) h->csrO = ev->y - r->scrollBar.top; /* FALLTHROUGH */ case Button3: if (r->scrollBar.style != R_SB_XTERM) { if (scrollbar_above_slider(ev->y))# ifdef RXVT_SCROLL_FULL rxvt_scr_page(r, ATAB(r), UP, r->TermWin.nrow-1);# else rxvt_scr_page(r, ATAB(r), UP, r->TermWin.nrow/4);# endif else if (scrollbar_b
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -