📄 ttysw_notify.c
字号:
#ifndef lint#ifdef sccsstatic char sccsid[] = "@(#)ttysw_notify.c 1.1 92/07/30";#endif#endif/* * Copyright (c) 1985, 1988 by Sun Microsystems, Inc. *//* * Notifier related routines for the ttysw. */#include <sys/types.h>#include <sys/file.h>#include <sys/time.h>#include <sys/resource.h>#include <sys/wait.h>#include <sgtty.h>#include <signal.h>#include <stdio.h>#include <errno.h>#include <ctype.h>#include <pixrect/pixrect.h>#include <pixrect/pixfont.h>#include <sunwindow/notify.h>#include <sunwindow/rect.h>#include <sunwindow/rectlist.h>#include <sunwindow/pixwin.h>#include <sunwindow/win_input.h>#include <sunwindow/win_notify.h>#include <sunwindow/defaults.h>#include <suntool/alert.h>#include <suntool/frame.h>#include <suntool/ttysw.h>#include <suntool/window.h>#include <suntool/tool_struct.h> /* tool.h must be before any indirect include of textsw.h */#include <suntool/ttysw_impl.h>/* #ifdef CMDSW */extern void ttysw_display_capslock();extern void ttynullselection();extern caddr_t textsw_get();extern Textsw_status textsw_set();extern void textsw_display();extern Cmdsw *cmdsw;extern struct ttysubwindow *_ttysw;/* #else */#include <suntool/charimage.h>#include <suntool/charscreen.h>#undef length#define ITIMER_NULL ((struct itimerval *)0)#define TTYSW_USEC_DELAY 100000 /* Duplicate of what's in ttysw_tio.c */Notify_value ttysw_itimer_expired();/* #endif CMDSW *//* #ifndef CMDSW */static Notify_value ttysw_win_input_pending();/* #endif CMDSW */Notify_value ttysw_text_input_pending();static Notify_value ttysw_pty_output_pending();Notify_value ttysw_pty_input_pending();Notify_value ttysw_prioritizer();void ttysw_sendsig();/* * These three procedures are no longer needed because the * pty driver bug that causes the ttysw to lock up is fixed. * void ttysw_add_pty_timer(); * void ttysw_remove_pty_timer(); * Notify_value ttysw_pty_timer_expired();*/void ttysw_sigwinch();/* shorthand - Duplicate of what's in ttysw_main.c */#define iwbp ttysw->ttysw_ibuf.cb_wbp#define irbp ttysw->ttysw_ibuf.cb_rbp#define iebp ttysw->ttysw_ibuf.cb_ebp#define ibuf ttysw->ttysw_ibuf.cb_buf#define owbp ttysw->ttysw_obuf.cb_wbp#define orbp ttysw->ttysw_obuf.cb_rbpint ttysw_waiting_for_pty_input; /* Accelerator to avoid excessive notifier activity */static ttysw_waiting_for_pty_output; /* Accelerator to avoid excessive notifier activity */Notify_func ttysw_cached_pri; /* Default prioritizer */extern Notify_value ttysw_text_destroy(); /* Destroy func for cmdsw */extern Notify_value ttysw_text_event(); /* Event func for cmdsw */extern int ttysw_scan_for_completed_commands();extern void ttysw_move_mark();/* Only extern for use by tty_window_object() in tty.c */ttysw_interpose(ttysw) Ttysw *ttysw;{ (void) notify_interpose_input_func((Notify_client)ttysw, ttysw_win_input_pending, (int)LINT_CAST(window_get((Window)(LINT_CAST(ttysw)), WIN_FD))); if (ttysw_getopt((caddr_t)ttysw, TTYOPT_TEXT)) { Textsw textsw = (Textsw) ttysw->ttysw_hist; (void)notify_interpose_event_func((Notify_client)textsw, ttysw_text_event, NOTIFY_SAFE); (void)notify_interpose_destroy_func((Notify_client)textsw, ttysw_text_destroy); (void) notify_interpose_input_func((Notify_client)textsw, ttysw_text_input_pending, (int)LINT_CAST(window_get((Window)(LINT_CAST(ttysw->ttysw_hist)), WIN_FD))); } (void) notify_set_input_func((Notify_client)ttysw, ttysw_pty_input_pending, ttysw->ttysw_pty); ttysw_waiting_for_pty_input = 1; ttysw_cached_pri = notify_set_prioritizer_func((Notify_client)ttysw, ttysw_prioritizer);}caddr_tttysw_create(tool, name, width, height) struct tool *tool; char *name; short width, height;{ struct toolsw *toolsw; extern struct pixwin *csr_pixwin; Bool retained; Ttysw *ttysw; /* Create an empty subwindow */ if ((toolsw = tool_createsubwindow(tool, name, width, height)) == (struct toolsw *) 0) return (NULL); /* Make the empty subwindow into a tty subwindow */ if ((toolsw->ts_data = ttysw_init(toolsw->ts_windowfd)) == NULL) return (NULL); ((Ttysw *)LINT_CAST(toolsw->ts_data))->ttysw_flags |= TTYSW_FL_USING_NOTIFIER; ttysw = (Ttysw *)LINT_CAST(toolsw->ts_data); /* Register with window manager */ if (ttysw_getopt((caddr_t)ttysw, TTYOPT_TEXT)) { toolsw->ts_data = (caddr_t)ttysw->ttysw_hist; (void)textsw_set((Textsw)ttysw->ttysw_hist, TEXTSW_TOOL, tool, 0); (void)ttysw_interpose(ttysw); } /* begin ttysw only */ retained = defaults_get_boolean("/Tty/Retained", (Bool)FALSE, (int *)NULL); if (win_register((char *)ttysw, csr_pixwin, ttysw_event, ttysw_destroy, (unsigned)((retained)? PW_RETAIN: 0))) return (NULL); /* Draw cursor on the screen and retained portion */ (void)drawCursor(0, 0); /* end ttysw only */ return ((caddr_t)ttysw);}intttysw_start(ttysw_client, argv) Ttysubwindow ttysw_client; char **argv;{ int pid; Ttysw *ttysw;#ifdef DEBUG Notify_func func; /* for debugging */#endif DEBUG ttysw = (Ttysw *)(LINT_CAST(ttysw_client)); if ((pid = ttysw_fork_it((caddr_t)ttysw, argv)) != -1) { /* Wait for child process to die */ (void) notify_set_wait3_func((Notify_client)(LINT_CAST(ttysw)), notify_default_wait3, pid);#ifdef DEBUG func = notify_get_output_func(ttysw, ttysw->ttysw_pty); func = notify_get_input_func(ttysw, ttysw->ttysw_pty); func = notify_get_prioritizer_func(ttysw); if (pid == -1) notify_dump(ttysw, 0, 2);#endif DEBUG } return (pid);}Notify_valuettysw_destroy(ttysw, status) Ttysw *ttysw; Destroy_status status;{ if (status != DESTROY_CHECKING) { /* * Pty timer is no longer needed because the * pty driver bug that causes the ttysw to lock up is fixed. * ttysw_remove_pty_timer(ttysw); */ (void) notify_set_itimer_func((Notify_client)(LINT_CAST(ttysw)), ttysw_itimer_expired, ITIMER_REAL, (struct itimerval *) 0, ITIMER_NULL); /* Sending both signal is to cover all bases */ /* This is the workaround for the poison pty bug in the kernel */ /* ttysw_sendsig(ttysw, (Textsw) 0, SIGTERM); ttysw_sendsig(ttysw, (Textsw) 0, SIGHUP); */ (void)win_unregister((char *)(LINT_CAST(ttysw))); if (ttysw->ttysw_hist) { window_set(ttysw->ttysw_hist, TEXTSW_CLIENT_DATA, 0, 0); } (void)ttysw_done((caddr_t)ttysw); return (NOTIFY_DONE); } return (NOTIFY_IGNORED);}voidttysw_sigwinch(ttysw) Ttysw *ttysw;{ int pgrp; int sig = SIGWINCH; /* * 2.0 tty based programs relied on getting SIGWINCHes at times other * then when the size changed. Thus, for compatibility, we also do * that here. However, I wish that I could get away with only sending * SIGWINCHes on resize. */ /* Notify process group that terminal has changed. */ if (ioctl(ttysw->ttysw_tty, TIOCGPGRP, &pgrp) == -1) { perror("ttysw_sigwinch, can't get tty process group"); return; } /* * Only killpg when pgrp is not tool's. This is the case of haven't * completed ttysw_fork yet (or even tried to do it yet). */ if (getpgrp(0) != pgrp) /* * killpg could return -1 with errno == ESRCH but this is OK. */ /* (void) killpg(pgrp, SIGWINCH); */ ioctl(ttysw->ttysw_pty, TIOCSIGNAL, &sig); return;}/* #ifdef CMDSW */voidttysw_sendsig(ttysw, textsw, sig) Ttysw *ttysw; Textsw textsw; int sig;{ int control_pg; /* Send the signal to the process group of the controlling tty */ if (ioctl(ttysw->ttysw_pty, TIOCGPGRP, &control_pg) >= 0) { /* * Flush our buffers of completed and partial commands. * Be sure to do this BEFORE killpg, or we'll flush * the prompt coming back from the shell after the * process dies. */ (void)ttysw_flush_input((caddr_t)ttysw); if (textsw) ttysw_move_mark(textsw, &cmdsw->pty_mark, (Textsw_index)textsw_get(textsw, TEXTSW_LENGTH), TEXTSW_MARK_DEFAULTS); cmdsw->cmd_started = 0; cmdsw->pty_owes_newline = 0; /* (void) killpg(control_pg, sig); */ ioctl(ttysw->ttysw_pty, TIOCSIGNAL, &sig); } else perror("ioctl");}/* #endif CMDSW *//* ARGSUSED */Notify_valuettysw_event(ttysw, event, arg, type) Ttysw *ttysw; Event *event; Notify_arg arg; Notify_event_type type;{ switch (event_id(event)) { case WIN_REPAINT: if (ttysw->ttysw_hist && cmdsw->cmd_started) { (void)ttysw_scan_for_completed_commands(ttysw, -1, 0); } (void)ttysw_display((Ttysubwindow)(LINT_CAST(ttysw))); return (NOTIFY_DONE); case WIN_RESIZE: (void)ttysw_resize(ttysw); return (NOTIFY_DONE); default: if (ttysw_eventstd(ttysw, event) == TTY_DONE) return (NOTIFY_DONE); else return (NOTIFY_IGNORED); }}ttysw_display(ttysw_client) Ttysubwindow ttysw_client;{ Ttysw *ttysw; ttysw = (Ttysw *)(LINT_CAST(ttysw_client)); if (ttysw_getopt((caddr_t)ttysw, TTYOPT_TEXT)) { textsw_display((Textsw)ttysw->ttysw_hist); } else { extern struct pixwin *csr_pixwin; extern wfd; (void)saveCursor(); (void)prepair(wfd, &csr_pixwin->pw_clipdata->pwcd_clipping); /* * If just hilite the selection part that is damaged then the other * non-damaged selection parts should still be visible, thus creating
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -