📄 teksw_ui.c
字号:
#ifndef lint#ifdef sccsstatic char sccsid[] = "@(#)teksw_ui.c 1.1 92/07/30 Copyr 1985 Sun Micro";#endif#endif/* * Copyright (c) 1985 by Sun Microsystems, Inc. *//* * User interface for teksw and tek * * Author: Steve Kleiman */#include <sys/types.h>#include <stdio.h>#include <signal.h>#include <setjmp.h>#include <errno.h>#include <sys/termios.h>#include <suntool/sunview.h>#include <suntool/canvas.h>#include <suntool/walkmenu.h>#include <suntool/scrollbar.h>#include <suntool/panel.h>#include <suntool/alert.h>#include "tek.h"#include "teksw_imp.h"#define abs(x) ((x) >= 0? (x): -(x))/********************* global data********************/static struct pr_size teksize = { /* tektronix 4014 screen size */ TXSIZE, TYSIZE};static struct ttysize tekttysize[4] = { {TEKFONT0ROW, TEKFONT0COL}, {TEKFONT1ROW, TEKFONT1COL}, {TEKFONT2ROW, TEKFONT2COL}, {TEKFONT3ROW, TEKFONT3COL},};/* wait cursor */extern Pixrect hglass_cursor_mpr;static struct cursor waitcursor = { 8, 8, PIX_SRC|PIX_DST, &hglass_cursor_mpr};extern struct pixrect stop_mpr;static struct cursor stop_cursor = { 7, 5, PIX_SRC|PIX_DST, &stop_mpr};struct pixfont *tekfont[NFONT];static void resize();static void tek_size();static void tek_putchar();static void tek_usrinput();static void drawalphacursor();static void removealphacursor();static void tek_blinkscreen();static int goodpos();static void goodcursor();static void badcursor();static int inimage();static void imagetotek();static void tektoimage();/* * Main I/O processing. *//* * user input */Notify_valueteksw_event(canvas, ep) Window canvas; register Event *ep;{ register struct teksw *tsp; int v; tsp = (struct teksw *)window_get(canvas, WIN_CLIENT_DATA); if (event_is_ascii(ep)) { if (goodpos(tsp, ep)) tek_kbdinput(tsp->temu_data, event_action(ep)); } else { switch (event_action(ep)) { default: return (NOTIFY_IGNORED); case WIN_RESIZE: resize(tsp); break; case KEY_PAGE_RESET: if (event_shift_is_down(ep)) tek_kbdinput(tsp->temu_data, RESET); else tek_kbdinput(tsp->temu_data, PAGE); break; case KEY_COPY: tek_kbdinput(tsp->temu_data, COPY); break; case KEY_RELEASE: tek_kbdinput(tsp->temu_data, RELEASE); break; case ACTION_PROPS: teksw_props(tsp); break; case MS_LEFT: if (event_is_down(ep)) { if (tsp->uiflags & GCURSORON) { if (goodpos(tsp, ep)) tek_kbdinput(tsp->temu_data, ' '); } else if (tsp->uiflags & PAGEFULL) { tek_kbdinput(tsp->temu_data, RELEASE); } } break; case MS_RIGHT: switch (v = (int)menu_show(tsp->menu, canvas, canvas_window_event(canvas, ep), 0)) { case COPY: case RESET: case PAGE: case RELEASE: tek_kbdinput(tsp->temu_data, v); break; } break; case LOC_RGNENTER: case LOC_MOVE: (void) goodpos(tsp, ep); break; case LOC_RGNEXIT: if ((tsp->uiflags & GCURSORON) && !(tsp->uiflags & BADCURSOR) && !inimage(tsp, ep->ie_locx, ep->ie_locy) ) { badcursor(tsp, ep->ie_locx, ep->ie_locy); } break; } } if (tsp->cursormode == ALPHACURSOR && !(tsp->uiflags & ACURSORON)) { tsp->uiflags |= ACURSORON; drawalphacursor(tsp); } if (tsp->uiflags & RESTARTPTY) { tsp->uiflags &= ~RESTARTPTY; (void) teksw_pty_input(tsp, tsp->pty); } return (NOTIFY_DONE);}/* * pty input */Notify_valueteksw_pty_input(tsp, fd) register struct teksw *tsp; int fd;{ register char *pbp; register int cc; extern int errno; if (tsp->uiflags & PAGEFULL) return (NOTIFY_DONE); if (tsp->ptyirp < tsp-> ptyiwp) { pbp = tsp->ptyirp; cc = tsp->ptyiwp - pbp; tsp->ptyirp = tsp->ptyiwp = 0; } else { pbp = tsp->ptyibuf; cc = read(fd, pbp, sizeof (tsp->ptyibuf)); if (cc < 0) { if (errno == EWOULDBLOCK) return (NOTIFY_DONE); else return (NOTIFY_IGNORED); } else if (cc > 0) { /* * Skip status byte for now. * Should do start/stop here? */ pbp++, cc--; } } if (cc > 0) { pw_batch_on(tsp->pwp); while (!(tsp->uiflags & PAGEFULL) && cc-- > 0) { tek_ttyinput(tsp->temu_data, *pbp++); } if (tsp->cursormode == ALPHACURSOR && !(tsp->uiflags & ACURSORON)) { tsp->uiflags |= ACURSORON; drawalphacursor(tsp); } pw_batch_off(tsp->pwp); if (tsp->uiflags & PAGEFULL) { tsp->ptyiwp = pbp + cc; tsp->ptyirp = pbp; cc = 0; } } return (cc >= 0? NOTIFY_DONE: NOTIFY_IGNORED);}/*ARGSUSED*//* * pty output */Notify_valueteksw_pty_output(tsp, fd) register struct teksw *tsp; int fd;{ register int cc; cc = write(tsp->pty, tsp->ptyorp, tsp->ptyowp - tsp->ptyorp); if (cc > 0) { tsp->ptyorp += cc; } if (tsp->ptyorp == tsp->ptyowp) { tsp->ptyorp = tsp->ptyowp = tsp->ptyobuf; (void) notify_set_output_func(tsp, NOTIFY_FUNC_NULL, tsp->pty); } return (cc > 0? NOTIFY_DONE: NOTIFY_IGNORED);}static voidresize(tsp) register struct teksw *tsp;{ if (tsp->imagesize.x > (int)window_get(tsp->canvas, WIN_WIDTH)) { if (window_get(tsp->canvas, WIN_HORIZONTAL_SCROLLBAR) == NULL) window_set(tsp->canvas, WIN_HORIZONTAL_SCROLLBAR, scrollbar_create( SCROLL_PAGE_BUTTONS, FALSE, 0), 0); } else { window_set(tsp->canvas, WIN_HORIZONTAL_SCROLLBAR, NULL, 0); } if (tsp->imagesize.y > (int)window_get(tsp->canvas, WIN_HEIGHT)) { if (window_get(tsp->canvas, WIN_VERTICAL_SCROLLBAR) == NULL) window_set(tsp->canvas, WIN_VERTICAL_SCROLLBAR, scrollbar_create( SCROLL_PAGE_BUTTONS, FALSE, 0), 0); } else { window_set(tsp->canvas, WIN_VERTICAL_SCROLLBAR, NULL, 0); }}voidteksw_props(tsp) register struct teksw *tsp;{ register Window panel; extern void hide_props(); extern void props_proc(); extern char *getenv(); if (tsp->props != NULL) { panel = (Window)window_get(tsp->props, WIN_CLIENT_DATA); } else { char *cp; tsp->props = window_create(tsp->owner, FRAME, FRAME_LABEL, "Tektool Properties", FRAME_SHOW_LABEL, TRUE, 0); panel = window_create(tsp->props, PANEL, 0); window_set(tsp->props, WIN_CLIENT_DATA, panel, 0); panel_create_item(panel, PANEL_BUTTON, PANEL_LABEL_Y, ATTR_ROW(0), PANEL_LABEL_X, ATTR_COL(0), PANEL_LABEL_IMAGE, panel_button_image(panel, "DONE", 0, 0), PANEL_NOTIFY_PROC, hide_props, PANEL_CLIENT_DATA, tsp, 0); tsp->straps_item = panel_create_item(panel, PANEL_TOGGLE, PANEL_LABEL_Y, ATTR_ROW(1), PANEL_LABEL_X, ATTR_COL(0), PANEL_CHOICE_STRINGS, "LF->CR", "CR->LF", "DEL=>LOY", "Echo", "Auto copy", "Local", "Destructive characters", 0, PANEL_DISPLAY_LEVEL, PANEL_CURRENT, PANEL_NOTIFY_PROC, props_proc, PANEL_CLIENT_DATA, tsp, 0); tsp->gin_item = panel_create_item(panel, PANEL_CHOICE, PANEL_LABEL_Y, ATTR_ROW(2), PANEL_LABEL_X, ATTR_COL(0), PANEL_LABEL_STRING, "GIN Terminator:", PANEL_CHOICE_STRINGS, "NONE", "CR", "CR,EOT", 0, PANEL_DISPLAY_LEVEL, PANEL_CURRENT, PANEL_NOTIFY_PROC, props_proc, PANEL_CLIENT_DATA, tsp, 0); tsp->marg_item = panel_create_item(panel, PANEL_CHOICE, PANEL_LABEL_Y, ATTR_ROW(2), PANEL_LABEL_STRING, "Page Full:", PANEL_CHOICE_STRINGS, "OFF", "MARGIN 1", "MARGIN 2", 0, PANEL_DISPLAY_LEVEL, PANEL_CURRENT, PANEL_NOTIFY_PROC, props_proc, PANEL_CLIENT_DATA, tsp, 0); tsp->copy_item = panel_create_item(panel, PANEL_TEXT, PANEL_LABEL_Y, ATTR_ROW(3), PANEL_LABEL_X, ATTR_COL(0), PANEL_LABEL_STRING, "Copy:", PANEL_VALUE, ((cp = getenv("TEKCOPY"))? cp: DEFAULTCOPY), 0); window_fit(panel); window_fit(tsp->props); } panel_set_value(tsp->straps_item, tsp->straps); switch (tsp->straps & GINTERM) { case GINNONE: panel_set_value(tsp->gin_item, 0); break; case GINCR: panel_set_value(tsp->gin_item, 1); break; case GINCRE: panel_set_value(tsp->gin_item, 2); break; } switch (tsp->straps & MARGIN) { case MARGOFF: panel_set_value(tsp->marg_item, 0); break; case MARG1: panel_set_value(tsp->marg_item, 1); break; case MARG2: panel_set_value(tsp->marg_item, 2); break; } window_set(tsp->props, WIN_SHOW, TRUE, 0);}/*ARGSUSED*/static voidhide_props(item, ep) Panel_item item; Event *ep;{ register struct teksw *tsp; tsp = (struct teksw *)panel_get(item, PANEL_CLIENT_DATA); window_set(tsp->props, WIN_SHOW, FALSE, 0);}/*ARGSUSED*/static voidprops_proc(item, value, ep) Panel_item item; unsigned int value; Event *ep;{ register struct teksw *tsp; tsp = (struct teksw *)panel_get(item, PANEL_CLIENT_DATA); if (item == tsp->straps_item) { tsp->straps &= ~(LFCR|CRLF|DELLOY|AECHO|ACOPY|LOCAL|CRT_CHARS); tsp->straps |= value; } else if (item == tsp->gin_item) { tsp->straps &= ~GINTERM; switch(value) { case 1: tsp->straps |= GINCR; break; case 2: tsp->straps |= GINCRE; break; } } else { tsp->straps &= ~MARGIN; switch(value) { case 1: tsp->straps |= MARG1; break; case 2: tsp->straps |= MARG2; break; } } tek_set_straps(tsp->temu_data, tsp->straps);}/* * Pop up an alert with a string */static voidconfirm(tsp, s) register struct teksw *tsp; char *s;{ (void) alert_prompt(tsp->owner, NULL, ALERT_MESSAGE_STRINGS, s, 0, ALERT_BUTTON_YES, "Confirm", 0);}static intgoodpos(tsp, ep) register struct teksw *tsp; register Event *ep;{ struct pr_pos tpos; if (tsp->uiflags & GCURSORON) { if (inimage(tsp, ep->ie_locx, ep->ie_locy)) { tpos.x = ep->ie_locx; tpos.y = ep->ie_locy; if (tsp->uiflags & BADCURSOR) { goodcursor(tsp); } imagetotek(tsp, &tpos); tek_posinput(tsp->temu_data, tpos.x, tpos.y); } else if (!(tsp->uiflags & BADCURSOR)) { badcursor(tsp, ep->ie_locx, ep->ie_locy); return (0); } } return (1);}static voidbadcursor(tsp, x, y) register struct teksw *tsp; register int x, y;{ register int flags; cursor_set(tsp->cursor, CURSOR_SHOW_CURSOR, TRUE, CURSOR_SHOW_CROSSHAIRS, FALSE, 0); window_set(tsp->canvas, WIN_CURSOR, tsp->cursor, 0); flags = 0; if (x < WXMIN(tsp)) { flags |= BADCURS_XMIN; x = WXMIN(tsp); } else if (x >= WXMAX(tsp)) { flags |= BADCURS_XMAX; x = WXMAX(tsp); } if (flags) { pw_vector(tsp->pwp, x, WYMIN(tsp), x, WYMAX(tsp), (PIX_SRC ^ PIX_DST), 1); } if (y < WYMIN(tsp)) { flags |= BADCURS_YMIN; y = WYMIN(tsp); } else if (y >= WYMAX(tsp)) { flags |= BADCURS_YMAX; y = WYMAX(tsp); } if (flags & (BADCURS_YMIN|BADCURS_YMAX)) { pw_vector(tsp->pwp, WXMIN(tsp), y, WXMAX(tsp), y, (PIX_SRC ^ PIX_DST), 1); } tsp->uiflags |= flags;}static voidgoodcursor(tsp) register struct teksw *tsp;{ register int flags; register int a; flags = tsp->uiflags & BADCURSOR; if (flags & (BADCURS_XMIN|BADCURS_XMAX)) { a = ((flags & BADCURS_XMIN)? WXMIN(tsp): WXMAX(tsp)); pw_vector(tsp->pwp, a, WYMIN(tsp), a, WYMAX(tsp), (PIX_SRC ^ PIX_DST), 1); } if (flags & (BADCURS_YMIN|BADCURS_YMAX)) { a = ((flags & BADCURS_YMIN)? WYMIN(tsp): WYMAX(tsp)); pw_vector(tsp->pwp, WXMIN(tsp), a, WXMAX(tsp), a, (PIX_SRC ^ PIX_DST), 1); } tsp->uiflags &= ~BADCURSOR; if (tsp->uiflags & GCURSORON) { cursor_set(tsp->cursor, CURSOR_SHOW_CURSOR, FALSE, CURSOR_SHOW_CROSSHAIRS, TRUE, 0); window_set(tsp->canvas, WIN_CURSOR, tsp->cursor, 0); }}/*****************************************************************************}/***************************************************************************** * * Tek emulator interface routines * *****************************************************************************/voidtek_move(td, x, y) caddr_t td; int x, y;{ register struct teksw *tsp; tsp = (struct teksw *) td; tsp->curpos.x = x; tsp->curpos.y = y; tektoimage(tsp, &tsp->curpos); if (tsp->uiflags & ACURSORON) { tsp->uiflags &= ~ACURSORON; removealphacursor(tsp); }}voidtek_draw(td, x, y) caddr_t td; int x, y;{ register struct teksw *tsp; struct pr_pos tpos; tsp = (struct teksw *) td; tpos.x = x; tpos.y = y; tektoimage(tsp, &tpos); if (tsp->type == VT_WRITETHRU) { tek_line(tsp, tsp->curpos.x, tsp->curpos.y, tpos.x, tpos.y, (PIX_SRC ^ PIX_DST), 0, tsp->style); pw_show(tsp->pwp); tek_line(tsp, tsp->curpos.x, tsp->curpos.y, tpos.x, tpos.y, (PIX_SRC ^ PIX_DST), 0, tsp->style); } else { tek_line(tsp, tsp->curpos.x, tsp->curpos.y, tpos.x, tpos.y, PIX_SRC, (tsp->type == VT_DEFOCUSED? 1: 0), tsp->style); } tsp->curpos = tpos;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -