koreth@ssyx.ucsc.edu (Steven Grimm) (03/03/89)
Submitted-by: sun.com!laidbak!katzung (Brian Katzung) Posting-number: Volume 2, Issue 22 Archive-name: uw/part04 #!/bin/sh # this is part 4 of a multipart archive # do not concatenate these parts, unpack them in order with /bin/sh # file WINMAIN.C continued # CurArch=4 if test ! -r s2_seq_.tmp then echo "Please unpack part 1 first!" exit 1; fi ( read Scheck if test "$Scheck" != $CurArch then echo "Please unpack part $Scheck next!" exit 1; else exit 0; fi ) < s2_seq_.tmp || exit 1 sed 's/^X//' << 'SHAR_EOF' >> WINMAIN.C X form_center(obj_tmp, &cx, &cy, &cw, &ch); X form_dial(FMD_START, 0, 0, 20, 10, cx, cy, cw, ch); X if (!fast) form_dial(FMD_GROW, 0, 0, 20, 10, cx, cy, cw, ch); X objc_draw(obj_tmp, 0, 5, cx, cy, cw, ch); X tmp = 0; X while (tmp != FUNCEXIT) X { X int i; X X tmp = form_do(obj_tmp, FUNCNAME); X switch (tmp) X { X case FUNCSHOW: X funcindex = atoi(ted_fnum->te_ptext) - 1; X if (funcindex < 0) X funcindex = NFSTRINGS - 3; X else if (funcindex > NFSTRINGS - 3) X funcindex = 0; X strcpy((char *) ted_tmp->te_ptext, fstrings[funcindex]); X objc_draw(obj_tmp, FUNCBODY, 5, cx, cy, cw, ch); X sprintf(ted_fnum->te_ptext, "%2d", funcindex+1); X objc_draw(obj_tmp, FUNCNAME, 5, cx, cy, cw, ch); X break; X case FUNCPREV: X funcindex --; X if (funcindex < 0) X funcindex = NFSTRINGS - 3; X sprintf(ted_fnum->te_ptext, "%2d", funcindex+1); X objc_draw(obj_tmp, FUNCNAME, 5, cx, cy, cw, ch); X strcpy((char *) ted_tmp->te_ptext, fstrings[funcindex]); X objc_draw(obj_tmp, FUNCBODY, 5, cx, cy, cw, ch); X break; X case FUNCNEXT: X funcindex ++; X if (funcindex > NFSTRINGS - 3) X funcindex = 0; X sprintf(ted_fnum->te_ptext, "%2d", funcindex+1); X objc_draw(obj_tmp, FUNCNAME, 5, cx, cy, cw, ch); X strcpy((char *) ted_tmp->te_ptext, fstrings[funcindex]); X objc_draw(obj_tmp, FUNCBODY, 5, cx, cy, cw, ch); X break; X case FUNCENT: X funcindex = atoi(ted_fnum->te_ptext) - 1; X strcpy(fstrings[funcindex], ted_tmp->te_ptext); X fstrings[funcindex][i] = ted_tmp->te_ptext[i]; X strcpy((char *) ted_tmp->te_ptext, fstrings[funcindex]); X objc_draw(obj_tmp, FUNCBODY, 5, cx, cy, cw, ch); X break; X } X objc_change(obj_tmp, tmp, 0, cx, cy, cw, ch, NONE, 1); X } X if (!fast) form_dial(FMD_SHRINK, 0, 0, 20, 10, cx, cy, cw, ch); X form_dial(FMD_FINISH, 0, 0, 20, 10, cx, cy, cw, ch); X objc_change(obj_tmp, tmp, 0, cx, cy, cw, ch, NONE, 0); X break; X X case MFREE: X memory(); X break; X X case MFAST: X menu_icheck(menubar, MFAST, fast); X fast = !fast; X break; X X case OVERSTRI: X overstrike = !overstrike; X menu_icheck(menubar, OVERSTRI, overstrike); X break; X X case FNTSYS: X case FNTOWN: X case FNTALT: X case FNTBIG: X case FNTTINY: X case FNTUNKNW: X /* Add new font menu items here! */ X for (cnt = 0; fontmenuobj[cnt] != 0; cnt++) X { X if (fontmenuobj[cnt] != msgbuff[4]) X { X if (cnt < fontsavail) X objc_change(menubar, fontmenuobj[cnt], 0, 0, 0, 0, 0, X NONE, 0); X else X objc_change(menubar, fontmenuobj[cnt], 0, 0, 0, 0, 0, X DISABLED, 0); X } X else X curfont = fnttbl[cnt]; X } X objc_change(menubar, msgbuff[4], 0, 0, 0, 0, 0, CHECKED, 0); X break; X X case PRTBOTOM: X if (outwind) X { X w[outwind].ptr_status = LOG_BOTOM; X printer_mark(outwind); X w_rename(outwind, NULL); X } X break; X X case PRTTOP: X if (outwind) X { X w[outwind].ptr_status = LOG_TOP; X printer_mark(outwind); X w_rename(outwind, NULL); X } X break; X X case PRTWIND: X if (outwind) X { X printer_mark(outwind); X dump_window(outwind); X } X break; X X case PRTSTOP: X if (outwind) X { X w[outwind].ptr_status = LOG_NONE; X printer_mark(outwind); X w_rename(outwind, NULL); X } X break; X X case INPUTWIN: X case PASTE: X sel_inp_mode = msgbuff[4]; X graf_mouse(USER_DEF, rmbmform); X break; X X case RESETAUX: X if (rs232_reset()) X Cauxout(0x11); /* send XOFF */ X break; X X case ASSRD: /* Assert RTS/DTR. */ X Offgibit(~0x18); X break; X X case RESRD: /* Reset RTS/DTR. */ X Ongibit(0x18); X break; X X case AUDIBELL: X audibell = !audibell; X objc_change(menubar, AUDIBELL, 0, 0, 0, 0, 0, X audibell? CHECKED: 0, 0); X break; X X case VISIBELL: X visibell = !visibell; X objc_change(menubar, VISIBELL, 0, 0, 0, 0, 0, X visibell? CHECKED: 0, 0); X break; X X case TOPONBEL: X toponbel = !toponbel; X objc_change(menubar, TOPONBEL, 0, 0, 0, 0, 0, X toponbel? CHECKED: 0, 0); X break; X X case SHRNKWIN: /* Shrink window to iconic size */ X if (outwind) X { X outwind = w_shrink(outwind); X outport = find_port(outwind); X } X break; X X case BOTTOMTO: /* send bottom window to top */ X w_bottom(); X break; X X case WINSTYLE: /* enable/disable sliders and arrows for new windows */ X sliders = !sliders; X menu_icheck(menubar, WINSTYLE, sliders); X break; X X case HIDEWIN: /* send top window to bottom */ X if (outwind = w_hide()) X { X outport = find_port(outwind); X printer_mark(outwind); X } X break; X X case MOVEWIN: X if (outwind) X { X graf_mouse(POINT_HAND, &dummy); X evnt_button(1, 1, 1, &mx, &my, &dummy, &dummy); X wind_get(outwind, WF_CURRXYWH, &dummy, &dummy, &ww, &wh); X if (graf_dragbox(ww, wh, mx, my, X scr_x, scr_y, scr_w + ww, scr_h + wh, &mx, &my)) X w_move(outwind, mx, my, ww, wh); X graf_mouse(sel_inp_mode? USER_DEF: ARROW, rmbmform); X } X break; X X case OSIZEWIN: X if (outwind) X { X outwind = w_full(outwind); X outport = find_port(outwind); X } X break; X X case CLOSEWIN: X if (outwind = proto_close(outwind)) X { X printer_mark(outwind); X outport = find_port(outwind); X } X if (!uw_runs && !find_wind(1)) X { X menu_tnormal(menubar, msgbuff[3], 1); X goto init; X } X break; X X case WINTITLE: /* enable/disable window headers */ X titles = !titles; X menu_icheck(menubar, WINTITLE, titles); X break; X X case SETCONF: /* set rs232 port configuration */ X getrsconf(); X if (s_dial(RSCONF, 3) == RCOK) X setrsconf(); X break; X X case WINCLEAR: /* clear current window */ X if (outwind) X { X w[outwind].ptr_status = LOG_NONE; X w_output(outwind, "\032"); X } X break; X } X menu_tnormal(menubar, msgbuff[3], 1); X break; X X case WM_NEWTOP: X case WM_TOPPED: X if (!locked) X w_top(msgbuff[3]); X break; X X case WM_SIZED: X case WM_MOVED: X if (!locked) X w_move(msgbuff[3], msgbuff[4], msgbuff[5], msgbuff[6], msgbuff[7]); X break; X X case WM_CLOSED: X if (locked) break; X if (cnt = proto_close(msgbuff[3])) X { X if (msgbuff[3] == outwind) /* was keyboard input window closed? */ X outwind = cnt; X printer_mark(outwind); X outport = find_port(outwind); X } X if (!uw_runs && !find_wind(1)) X { X goto init; X } X break; X X case WM_REDRAW: X if (highlighted_wdes == msgbuff[3]) X { /* this window has highlighted text, redraw all of window*/ X register struct wi_str *wp = &w[msgbuff[3]]; X w_redraw(msgbuff[3], FM_COPY, wp->x, wp->y, wp->w, wp->h); X } X else X /* redraw only damaged part */ X w_redraw(msgbuff[3], FM_COPY, msgbuff[4], msgbuff[5], msgbuff[6], msgbuff[7]); X break; X X case WM_FULLED: X if (locked) break; X outwind = w_full(msgbuff[3]); X outport = find_port(outwind); X break; X X case WM_ARROWED: X if (!locked) X w_arrow(msgbuff[3], msgbuff[4]); X break; X X case WM_HSLID: X case WM_VSLID: X if (!locked) X w_slide(msgbuff[3], msgbuff[0] == WM_HSLID, msgbuff[4]); X break; X } X } X if ((event & MU_BUTTON) && ! locked) X { X if (sel_inp_mode && buttonstate) /* select input mode and button down */ X { X int found; X X graf_mouse(ARROW, &dummy); X if ((found = wind_find(mx, my)) != 0) { X outwind = found; X outport = find_port(outwind); X if (sel_inp_mode == PASTE) X proto_out(outport, pastebuff, strlen(pastebuff)); X } X evnt_button(1, 2, 0, &dummy, &dummy, &dummy, &dummy); X buttonstate = 0; X sel_inp_mode = FALSE; X } X else if (my < scr_y) /* is mouse on menu bar? */ X { /* yes, disable menu bar if button down */ X if (buttonstate) X { X objc_change(menubar, DESK, 0, 0, 0, 0, 0, X menonoff? DISABLED: NORMAL, menonoff); X menu_bar(menubar, menonoff = !menonoff); X if (menonoff) X graf_mouse(ARROW, &dummy); X else X graf_mouse(USER_DEF, rmbmform); X evnt_button(1, 2, 0, &dummy, &dummy, &dummy, &dummy); X buttonstate = 0; X } X } X else /* button click in work area */ X { /* handle text selection or output or mouse packet */ X int found, found1, x1, y1, x2, y2, w_x, w_y, w_w, w_h; X X if ((found = wind_find(mx, my)) != 0) X { X wind_get(found, WF_WORKXYWH, &w_x, &w_y, &w_w, &w_h); X if (mx >= w_x && mx < w_x + w_w && my >= w_y && my <w_y + w_h) X { /* in window, fill paste buffer */ X if (clicks > 1 && buttonstate) X { X y1 = (my - w_y - Y0) / w[found].font->inc_y; X copy_text(found, 0, y1, w[found].x_chrs - 1, y1, pastebuff); X evnt_button(3, 2, 0, &dummy, &dummy, &dummy, &dummy); X regionflag = 0; X } X else if (buttonstate) /* if button down */ X { X x1 = (mx - w_x - X0) / w[found].font->inc_x; X y1 = (my - w_y - Y0) / w[found].font->inc_y; X regionflag = 1; X found1 = found; X } X else if (regionflag && found == found1) X { /* button up */ X x2 = (mx - w_x - X0) / w[found].font->inc_x; X y2 = (my - w_y - Y0) / w[found].font->inc_y; X if (y2 == y1 && x2 == x1) X { /* simple click on char; select word */ X copy_word(found, x1, y1, pastebuff); X } X else if (y2 > y1 || (y2 == y1 && x2 > x1)) X copy_text(found, x1, y1, x2-1, y2, pastebuff); X else X copy_text(found, x2+1, y2, x1, y1, pastebuff); X } X } X else X { /* in border */ X /* send paste buffer and select keyboard window*/ X if (buttonstate) /* if button down */ X { X char * pptr = pastebuff; X outwind = found; X outport = find_port(outwind); X if (clicks > 1) X proto_out(outport, pptr, strlen(pptr)); X } X regionflag = 0; X } X } X else X { /* not in window or border */ X /* clear paste buffer and erase any current marks */ X pastebuff[0] = '\0'; X regionflag = 0; X copy_text(1, 1, 1, 0, 0, pastebuff); X } X } X buttonstate = buttonstate? 0: 2; /* toggle buttonstate */ X } X if (event & MU_M1) /* mouse moved into or out of work area */ X { X if (!sel_inp_mode && !menonoff && !locked) X graf_mouse(m1inout? USER_DEF: ARROW, rmbmform); X m1inout = ! m1inout; X } X } X} X/* X * printer_mark(wnd) places check marks in the apropriate places in the X * printer menu. X */ Xprinter_mark (wnd) X{ X objc_change(menubar, PRTBOTOM, 0, 0, 0, 0, 0, X (w[wnd].ptr_status & LOG_BOTOM)? CHECKED: NONE, 0); X X objc_change(menubar, PRTTOP, 0, 0, 0, 0, 0, X (w[wnd].ptr_status & LOG_TOP)? CHECKED: NONE, 0); X} X X/* X * s_dial performs a simple dialog with buttons and text only. X * The index of the terminating button is returned. X * If action == 1, the dialog is displayed. If action == 2, it is X * removed. If action == 3, both operations are done and form_do is X * called. X */ Xint s_dial(tree, action) Xint tree, action; X{ X int tmp = 0; X int cx, cy, cw, ch; X OBJECT *obj_tmp; X X rsrc_gaddr(R_TREE, tree, &obj_tmp); X form_center(obj_tmp, &cx, &cy, &cw, &ch); X if (action & 1) { X form_dial(FMD_START, 0, 0, 20, 10, cx, cy, cw, ch); X if (!fast) form_dial(FMD_GROW, 0, 0, 20, 10, cx, cy, cw, ch); X objc_draw(obj_tmp, 0, 5, cx, cy, cw, ch); X } X if (action == 3) { X tmp = form_do(obj_tmp, 0); X } X if (action & 2) { X if (!fast) form_dial(FMD_SHRINK, 0, 0, 20, 10, cx, cy, cw, ch); X form_dial(FMD_FINISH, 0, 0, 20, 10, cx, cy, cw, ch); X objc_change(obj_tmp, tmp, 0, cx, cy, cw, ch, NONE, 0); X } X return (tmp); X} X X/* X * set_menu_string sets the menu string for the specified menu object to X * newstr. X */ Xset_menu_string(newstr, object) Xregister char * newstr; Xint object; X{ X register char * oldstr; X X oldstr = (char *) menubar[object].ob_spec + 2; X while (*oldstr && *newstr) X *oldstr++ = *newstr++; X if (*oldstr) X *oldstr = ' '; X} X Xsize_dial() X{ X /* X * Enter rows and columns dialog X */ X int cx, cy, cw, ch; X char *rowstr, *colstr; X rsrc_gaddr(R_TREE, WINDSIZE, &obj_tmp); X ted_tmp = (TEDINFO *) obj_tmp[WINDROWS].ob_spec; X rowstr = ((char *)ted_tmp->te_ptext); X if (atoi(rowstr) < 2) X strcpy (rowstr, "24"); X ted_tmp = (TEDINFO *) obj_tmp[WINDCOLS].ob_spec; X colstr = ((char *)ted_tmp->te_ptext); X if (atoi(colstr) < 2) X strcpy (colstr, "80"); X form_center(obj_tmp, &cx, &cy, &cw, &ch); X form_dial(FMD_START, 0, 0, 20, 10, cx, cy, cw, ch); X if (!fast) X form_dial(FMD_GROW, 0, 0, 20, 10, cx, cy, cw, ch); X objc_draw(obj_tmp, 0, 5, cx, cy, cw, ch); X tmp = form_do(obj_tmp, WINDROWS); X if (!fast) X form_dial(FMD_SHRINK, 0, 0, 20, 10, cx, cy, cw, ch); X form_dial(FMD_FINISH, 0, 0, 20, 10, cx, cy, cw, ch); X objc_change(obj_tmp, tmp, 0, cx, cy, cw, ch, NONE, 0); X if (tmp == WINDCANC) X return(FALSE); X xsiz = atoi(colstr); X ysiz = atoi(rowstr); X if (xsiz < 2) X xsiz = 2; X if (xsiz > 300) X xsiz = 300; X if (ysiz < 2) X ysiz = 2; X if (ysiz > 300) X ysiz = 300; X return (TRUE); X} SHAR_EOF chmod 0600 WINMAIN.C || echo "restore of WINMAIN.C fails" sed 's/^X//' << 'SHAR_EOF' > WINPROC.C && X/* X * This file contains subroutines which deal with other processes X */ X#include <obdefs.h> X#include <gemdefs.h> X#include <stdio.h> X#include <osbind.h> X#include <xbios.h> X#include "wind.h" X#include "uw.h" X#include "windefs.h" X Xextern char * environ; X Xextern struct wi_str w[]; Xextern int fast; Xextern int scr_x, scr_y, scr_w, scr_h; /* size of screen */ Xextern OBJECT *menubar; X Xchar cmdpath[40] = "e:\\bin\\*.*"; X /* Path for command execution */ Xchar cmdname[40] = "msh.prg"; /* Name of command to run */ Xchar cmdargs[40] = " "; /* Arguments for command */ X X/* X * Exec process from dialog. X */ Xint do_exec() X{ X int status = 0; X int confbutt; X X fsel_input(cmdpath, cmdname, &confbutt); X if (confbutt) { X extern char * rindex(); X char cmdstr[80]; X char cmdargv[40]; X char *argv[20]; X char * ind; X OBJECT *obj_tmp; X TEDINFO *ted_tmp; X int cx, cy, cw, ch, tmp; X X strcpy(cmdstr, cmdpath); X ind = rindex(cmdstr, '\\'); X if (ind) * ++ind = '\0'; X strcat(cmdstr, cmdname); X form_dial(FMD_START, 0, 0, 0, 0, scr_x, scr_y, scr_w, scr_h); X /* save screen */ X X rsrc_gaddr(R_TREE, PARAM, &obj_tmp); X ted_tmp = (TEDINFO *) obj_tmp[PARAMSTR].ob_spec; X strcpy(ted_tmp->te_ptext, cmdargs); X form_center(obj_tmp, &cx, &cy, &cw, &ch); X if (!fast) form_dial(FMD_GROW, 0, 0, 20, 10, cx, cy, cw, ch); X objc_draw(obj_tmp, 0, 5, cx, cy, cw, ch); X tmp = form_do(obj_tmp, PARAMSTR); X if (!fast) form_dial(FMD_SHRINK, 0, 0, 20, 10, cx, cy, cw, ch); X objc_change(obj_tmp, tmp, 0, cx, cy, cw, ch, NONE, 0); X if (tmp != OKEXEC) { X form_dial(FMD_FINISH, 0, 0, 0, 0, scr_x, scr_y, scr_w, scr_h); X return(0); X } X strcpy(cmdargs, ted_tmp->te_ptext); X strcpy(cmdargv, cmdargs); X X graf_mouse(M_OFF, NULL); /* turn mouse off */ X menu_bar(menubar, 0); /* menu bar off */ X Cconws("\033E\033e"); /* clear screen, cursor on */ X ind = cmdargv; X argv[0] = cmdname; X tmp = 1; X while (*ind != '\0') { X while (*ind == ' ' && *ind != '\0'){ X *ind = '\0'; X ++ind; X } X argv[tmp++] = ind; X while (*ind != ' ' && *ind != '\0') X ++ind; X } X argv[tmp] = NULL; X status = execve(cmdstr, argv, environ); X sleep(1); X Cconws("\033E\033f"); /* clear screen, cursor off */ X form_dial(FMD_FINISH, 0, 0, 0, 0, scr_x, scr_y, scr_w, scr_h); X menu_bar(menubar, 1); /* menu bar on */ X graf_mouse(M_ON, NULL); /* turn mouse on */ X } X return(status); X} X X/* X * Set current path with dialog. X */ Xint do_path() X{ X int status = 0; X int confbutt; X char curpath[80]; X char ignore[40] = ""; X int drv; X X curpath[0] = Dgetdrv() + 'a'; X curpath[1] = ':'; X Dgetpath(curpath+2, 0); X strcat(curpath, "\\*.*"); X fsel_input(curpath, ignore, &confbutt); X if (confbutt) { X extern char * index(), *rindex(); X char * ind; X ind = index(curpath, ':'); X if (ind) { X drv = *(ind - 1); X if (drv > '\\') X drv -= 'a'; X else X drv -= 'A'; X if (drv >= 0 && drv <= 15) X Dsetdrv(drv); X } X else X ind = curpath; X *rindex(ind, '\\') = 0; X status = Dsetpath(++ind); X } X return(status); X} SHAR_EOF chmod 0600 WINPROC.C || echo "restore of WINPROC.C fails" sed 's/^X//' << 'SHAR_EOF' > WINPROTO.C && X/* X * This file contains the routines which implement the uw protocol. X * Code has been migrating here from winmain.c, but its not all here yet. X */ X X#include <stdio.h> X#include <osbind.h> X#include <gemdefs.h> X#include "wind.h" X#include "uw.h" X#include "windefs.h" X X#define LIMIT 300 X Xextern struct wi_str w[]; Xextern int outport; /* ports used with uw */ Xextern int inwind, outwind; /* windows for input/output */ Xextern int uw_runs; /* is uw running ? */ XFNT *curfont; /* font in use */ X X/* proto_out sends length chars from str to the window defined by outport. */ Xproto_out(outport, str, length) Xint outport, length; Xchar *str; X X{ Xstatic int oldoutport = 1; Xint key, i; Xint outwind; X Xoutwind = find_wind(outport); X if (w[outwind].w_local == TRUE) /* local window? */ X { X char *found, *index(); X char strcr[3] = "\r\n"; X X str[length] = '\0'; X while (found = index(str, '\r')) X { X char line[500]; X strncpy(line, str, found - str); X line[found-str] = '\0'; X w_output(outwind, line); X w_output(outwind, strcr); X str = found + 1; X } X w_output(outwind, str); X return; X } X for (key = *str, i = 0; i < length; key = str[++i]) X { X if (uw_runs) X { X if (outport != oldoutport) X { X xmitcmd(CB_FN_ISELW|outport); X oldoutport = outport; X } X if (key & 0x80) { X key &= 0x7f; X xmitcmd(CB_FN_META); X } X switch (key) X { X case XON: X xmitcmd(CB_FN_CTLCH|CB_CC_ON); X break; X X case XOFF: X xmitcmd(CB_FN_CTLCH|CB_CC_OFF); X break; X X case IAC: X xmitcmd(CB_FN_CTLCH|CB_CC_IAC); X break; X X default: X Bconout(1, key); X break; X } X } else X Bconout(1, key); /* need mask with 0x7f? */ X } X} X X/* X * proto_close closes the current window and notifies the remote. The new X * current window is returned. X */ Xint proto_close(curwind) Xint curwind; X{ X long dummy; X X if (uw_runs && (find_port(curwind) < MAX_WIND)) X { X xmitcmd(CB_FN_KILLW|find_port(curwind)); X } X w_close(curwind); X wind_get(0, WF_TOP, &curwind, &dummy, &dummy, &dummy); X return (curwind); X/* } else X { X w_close(curwind); X return (0); X } */ X} X X/* proto_in receives characters from the serial port. */ Xproto_in() X#define NORMSTATE 0 X#define IACSTATE 1 X/* #define METASTATE 2 replaced with seenmeta flag. */ X#define INITSTATE 3 X{ X register char *ptr; X char str[LIMIT+2]; X register char chr; X register int cnt; X long dummy; X static int state; X static int seenmeta = 0; X X ptr = str; X cnt = 0; X while (Bconstat(1) && cnt++<LIMIT) X { X chr = Bconin(1)&0x7f; X switch (state) X { X case NORMSTATE: X if (!chr || chr=='\177') continue; X if (chr == IAC) X { X if (uw_runs) X state = IACSTATE; X else X state = INITSTATE; X continue; X } X if (seenmeta) { X seenmeta = 0; X *ptr++ = chr|0x80; X } X else *ptr++ = chr; X break; X case INITSTATE: X if (chr == CB_FN_MAINT | CB_MF_ENTRY){ X xmitcmd(CB_FN_MAINT|CB_MF_ENTRY); X uw_runs = 1; X outport = 0; X outwind = 0; X } X else { X *ptr++ = IAC; X *ptr++ = chr; X } X state = NORMSTATE; X break; X case IACSTATE: X state = NORMSTATE; X if (chr&CB_DIR_MTOH) continue; X switch (chr&CB_FN) X { X case CB_FN_NEWW: X outport = w_open(chr&CB_WINDOW, "Terminal", curfont->def_win_x, X curfont->def_win_y); X outwind = find_wind(outport); X xmitcmd(CB_FN_ISELW|outport); X break; X X case CB_FN_KILLW: X w_close(find_wind(chr&CB_WINDOW)); X wind_get(0, WF_TOP, &outwind, &dummy, &dummy, &dummy); X outport = find_port(outwind); X break; X X case CB_FN_OSELW: X if (inwind != find_wind(chr&CB_WINDOW)) X { X *ptr = '\0'; X if (ptr != str) X { X if (w[inwind].kerm_act) X rpack(" ", NULL, str); X else X w_output(inwind, str); X } X ptr = str; X } X inwind = find_wind(chr&CB_WINDOW); X break; X X case CB_FN_META: X seenmeta = 1; X break; X X case CB_FN_CTLCH: X switch (chr&CB_CC) X { X case CB_CC_IAC: X if (seenmeta) { X seenmeta = 0; X *ptr++ = IAC|0x80; X } X else *ptr++ = IAC; X break; X X case CB_CC_ON: X if (seenmeta) { X seenmeta = 0; X *ptr++ = XON|0x80; X } X else *ptr++ = XON; X break; X X case CB_CC_OFF: X if (seenmeta) { X seenmeta = 0; X *ptr++ = XOFF|0x80; X } X else *ptr++ = XOFF; X X break; X } X break; X X case CB_FN_MAINT: X switch (chr&CB_MF) X { X case CB_MF_ENTRY: X xmitcmd(CB_FN_MAINT|CB_MF_ENTRY); X uw_runs = 1; X outport = 0; X outwind = 0; X break; X X case CB_MF_EXIT: X uw_runs = 0; X return (-1); X } X break; X } X break; X } X } X *ptr = '\0'; X if (ptr!=str) X { X if (w[inwind].kerm_act) X rpack(" ", NULL, str); X else X w_output(inwind, str); X } X return (0); X} SHAR_EOF chmod 0600 WINPROTO.C || echo "restore of WINPROTO.C fails" sed 's/^X//' << 'SHAR_EOF' > WINSUBR.C && X/* subroutines for multi-window terminal emulation X */ X X#include <obdefs.h> X#include <gemdefs.h> X#include <osbind.h> X#include <stdio.h> X#include "wind.h" X#include "windefs.h" X Xextern int handle; X X/* variables used by various routines X */ X Xlong dummy; /* dummy return variable */ Xextern int outwind, outport; /* window selection */ Xextern int scr_x, scr_y; /* size of the screen */ Xextern int scr_w, scr_h; Xextern int fast; /* flag for fast open/close */ Xextern int overstrike; Xextern int sliders; /* flag for sliders on new windows */ Xextern int titles; /* flag for title bars on new windows */ Xint tmp; /* temporary for anything... */ Xextern char alert[300]; /* used for alerts */ Xextern FNT *curfont; /* current font */ Xextern MFDB screen_mf; /* screen descriptor */ Xextern int mouse; /* for mouse on/off */ Xextern int audibell; /* What happens on BEL? */ Xextern int visibell; Xextern int toponbel; X Xstruct wi_str w[MAX_WIND]; X X/* the program code... X */ X Xchar *getmem(size) Xregister long size; X{ X char *got; X X got = (char *) Malloc(size); X#ifdef DEBUG X printf("alloc returned %lx of %ld size\n", got, size); X#endif X if (got == NULL) X { X sprintf(alert, "[1][Could not get %ld bytes][Ok]", size); X form_alert(1, alert); X } else X { X bzero(got, size); X } X return got; X} X Xbzero(ptr, size) Xregister char *ptr; Xregister long size; X{ X while (size--) X *ptr++ = 0; X} X X/* find_port maps from window handles to UW port identifiers X */ X Xfind_port(wnd) X{ X return w[wnd].port; X} X X/* find_wind maps from port ids to window handles X */ X Xfind_wind(port) X{ Xint i; X X for (i=1; i<MAX_WIND; i++) X if (w[i].port == port) return i; X return 0; X} X X/* w_open opens a window with the supplied name and port and returns a port X * number. If port was zero, a free port is chosen. X */ X Xw_open(port, name, xsiz, ysiz) Xchar *name; X{ X register struct wi_str *wp; X int wdes; X int i, cnt, wtyp; X int tmp_x, tmp_y, tmp_w, tmp_h; X X if (port && find_wind(port)) return port; /* this window is already open */ X if (!port) X { X for (i=1; i<MAX_WIND; i++) X { X if (!find_wind(i)) X { X port = i; /* a free port */ X break; X } X } X } X X wtyp = (sliders ? WI_WITHSLD : 0) | (titles ? WI_NOSLD : 0); X wind_calc(0, wtyp, 0, 0, curfont->inc_x*xsiz+2*X0, X curfont->inc_y*ysiz+2*Y0, &dummy, &dummy, &tmp_w, &tmp_h); X if (tmp_w>scr_w) X tmp_w = scr_w; /* full size <= screen size */ X tmp_x = 10*(port-1); X if (tmp_h>scr_h) X tmp_h = scr_h; X tmp_y = scr_y+16*(port-1); X X wdes = wind_create(wtyp, tmp_x, tmp_y, tmp_w, X tmp_h); X if (wdes < 0) X { X form_alert(1, "[1][Sorry, GEM has|no more windows|for us...][Ok]"); X return 0; X } X wp = &w[wdes]; X wp->wi_w = X0*2 + curfont->inc_x*xsiz; X wp->wi_h = Y0*2 + curfont->inc_y*ysiz; X wp->port = port; X if (!fast) X graf_growbox(0, 0, 20, 10, tmp_x, tmp_y, tmp_w, tmp_h); X wind_open(wdes, tmp_x, tmp_y, tmp_w, tmp_h); X wind_get(wdes, WF_WORKXYWH, &wp->x, &wp->y, &wp->w, &wp->h); X wp->fulled = 0; X wp->used = 1; X wp->x_off = 0; X wp->y_off = 0; X wp->px_off = 0; X wp->py_off = 0; X wp->m_off = wp->x & 15; X wp->cur_x = X0; X wp->cur_y = Y0; X wp->top_y = Y0; X wp->font = curfont; X wp->x_chrs = xsiz; X wp->y_chrs = ysiz; X wp->wi_mf.wpix = 2*X0 + xsiz*curfont->inc_x; X wp->wi_mf.hpix = 2*Y0 + ysiz*curfont->inc_y; X#ifdef KOPY X wp->wi_mf.wwords = ((wp->wi_mf.wpix>>5) +1) << 1; X#else X wp->wi_mf.wwords = (wp->wi_mf.wpix>>4) +1; X#endif X wp->wi_mf.ptr = getmem(((long)wp->wi_mf.hpix+wp->font->inc_y*MAXSCROLLED) X *wp->wi_mf.wwords*2); X wp->wi_mf.format = 0; X wp->wi_mf.planes = 1; X wp->ptr_status = LOG_NONE; X wp->wi_style = wtyp; X w_rename(wdes, name); X strcpy(wp->wi_fpath, ".\\*.*"); X wp->top_age = 1; X for (cnt = 1; cnt < MAX_WIND; cnt++) X if (w[cnt].port != 0) X w[cnt].top_age++; X X setvslide(wdes); X sethslide(wdes); X X return wp->port; X} X X/* w_closei removes a window but does not release its storage. X * This is used if the window contents must be saved for later use. X */ X Xw_closei(wdes) X{ X int xx, yy, ww, hh; X register struct wi_str *wp = &w[wdes]; X X if (!wp->used) return; X if (wp->wi_lfd) X fclose(wp->wi_lfd); X wind_get(wdes, WF_CURRXYWH, &xx, &yy, &ww, &hh); X wind_close(wdes); X if (!fast) X graf_shrinkbox(0, 0, 20, 10, xx, yy, ww, hh); X wind_delete(wdes); X} X X/* w_close removes a window. Most work is done by GEM, although w_close X * does some cleanup functions, too. X */ X Xw_close(wdes) X{ X register struct wi_str *wp = &w[wdes]; X X if (!wp->used) return; X w_closei(wdes); X Mfree(wp->wi_mf.ptr); X bzero(wp, (long)sizeof (struct wi_str)); X} X X/* w_resize resizes an existing window. X */ X Xw_resize(wdes, xsiz, ysiz) X{ X register struct wi_str *wp1 = &w[wdes]; X struct wi_str *wp2; X struct wi_str ws; X static int c[8]; X int port, wind, i; X X if (!wp1->used) return; X ws = *wp1; X port = find_port(wdes); X w_closei(wdes); X bzero(wp1, (long)sizeof (struct wi_str)); X port = w_open(port, "", xsiz, ysiz); X wind = find_wind(port); X wp2 = &w[wind]; X c[0] = ws.m_off; X c[1] = ws.top_y + max(0, ws.wi_mf.hpix - wp2->wi_mf.hpix); X c[2] = c[0] + min(ws.wi_mf.wpix, wp2->wi_mf.wpix); X c[3] = c[1] + min(ws.wi_mf.hpix, wp2->wi_mf.hpix); X c[4] = wp2->m_off; X c[5] = wp2->top_y; X c[6] = c[4] + min(ws.wi_mf.wpix, wp2->wi_mf.wpix); X c[7] = c[5] + min(ws.wi_mf.hpix, wp2->wi_mf.hpix); X /* copy screen */ X vro_cpyfm(handle, FM_COPY, c, &ws.wi_mf, &wp2->wi_mf); X /* copy parameters */ X wp2->inverse = ws.inverse; X wp2->insmode = ws.insmode; X if (wp2->font != ws.font) X { X wp2->cur_x = X0; X wp2->cur_y = (wp2->y_chrs - 1) * wp2->font->inc_y + Y0; X } X else X { X wp2->cur_x = (wp2->x_chrs - 1) * wp2->font->inc_x + X0; X if (ws.cur_x < wp2->cur_x) X wp2->cur_x = ws.cur_x; X wp2->cur_y = max(0, ws.cur_y - c[1]) + Y0; X } X wp2->state = ws.state; X for (i=0; i<80; i++) wp2->nuname[i] = ws.nuname[i]; X for (i=0; i<80; i++) wp2->wi_fpath[i] = ws.wi_fpath[i]; X for (i=0; i<20; i++) wp2->wi_fname[i] = ws.wi_fname[i]; X wp2->nuptr = ws.nuptr; X wp2->ptr_status = ws.ptr_status; X wp2->wi_lfd = ws.wi_lfd; X wp2->kerm_act = ws.kerm_act; X w_rename(wind, ws.name); X X Mfree(ws.wi_mf.ptr); X return port; X} X X/* w_rename changes the title bar of a window X */ X Xw_rename(wdes, name) Xchar *name; X{ X register struct wi_str *wp = &w[wdes]; X X if (name) X strcpy(wp->name, name); X if (wp->wi_style & NAME) X { X sprintf(wp->dname, " %s%s %s ", (wp->ptr_status != LOG_NONE)? "\275": "", X wp->wi_lfd? "\237": "", wp->name); X wind_set(wdes, WF_NAME, wp->dname + (wp->dname[1] == ' '), 0, 0); X } X} X X/* w_redraw redraws part of the screen from window contents. X * The coordinates are screen relative. X */ X Xw_redraw(wdes, logic, xx, yy, ww, hh) X{ X static int c[8]; X static GRECT t1, t2; X register struct wi_str *wp = &w[wdes]; X X if (xx+ww > scr_w) X ww = scr_w - xx; X if (yy+hh > scr_h+scr_y) X hh = scr_h+scr_y - yy; X t2.g_x = xx; t2.g_y = yy; X t2.g_w = ww; t2.g_h = hh; X t1.g_x = wp->x; t1.g_y = wp->y; X t1.g_w = wp->w; t1.g_h = wp->h; X if (!rc_intersect(&t2, &t1)) return; /* nothing to do... */ X wind_update(TRUE); X wind_get(wdes, WF_FIRSTXYWH, &t1.g_x, &t1.g_y, &t1.g_w, &t1.g_h); X while (t1.g_w && t1.g_h) X { X if (rc_intersect(&t2, &t1)) X { X if (mouse) X { X /* we have to do graphics, so switch the mouse off. X * mouse will be switched on again in main loop. X * this is ugly, but it improves speed a bit... X */ X mouse = 0; X graf_mouse(M_OFF, NULL); X } X#ifdef KCOPY X tfbmr(wp->wi_mf.ptr, t1.g_x - wp->x + wp->x_off + wp->m_off, X t1.g_y - wp->y + wp->y_off + wp->top_y - Y0, wp->wi_mf.wwords >> 1, X screen_mf.ptr, t1.g_x, t1.g_y, screen_mf.wwords >> 1, X t1.g_w, t1.g_h, logic); X#else X c[0] = t1.g_x - wp->x + wp->x_off + wp->m_off; X c[1] = t1.g_y - wp->y + wp->y_off + wp->top_y - Y0; X c[2] = c[0] + t1.g_w - 1; X c[3] = c[1] + t1.g_h - 1; X c[4] = t1.g_x; X c[5] = t1.g_y; X c[6] = c[4] + t1.g_w - 1; X c[7] = c[5] + t1.g_h - 1; X vro_cpyfm(handle, logic, c, &wp->wi_mf, &screen_mf); X#endif X } X wind_get(wdes, WF_NEXTXYWH, &t1.g_x, &t1.g_y, &t1.g_w, &t1.g_h); X } X if (!fast && !mouse) X { X mouse = 1; X graf_mouse(M_ON, NULL); X } X wind_update(FALSE); X} X X/* w_update copies a portion of the window to the screen. Coordinates X * are window-relative X */ X Xw_update(wdes, logic, xx, yy, ww, hh) X{ X register struct wi_str *wp = &w[wdes]; X X w_redraw(wdes, logic, xx + wp->x - wp->x_off, X yy + wp->y - wp->y_off - wp->top_y + Y0, ww, hh); X} X X/* w_move sets the window's idea of its own position on the screen X */ X Xw_move(wdes, xx, yy, ww, hh) X{ X register struct wi_str *wp = &w[wdes]; X int flag = 0; X int m_w, m_h; X int x1, x2; X int tmp; X X wind_calc(1, wp->wi_style, xx, yy, ww, hh, &dummy, &dummy, &m_w, &m_h); X if (tmp = (m_w-2*X0)%wp->font->inc_x) X { X ww -= tmp; X m_w -= tmp; X } X if (tmp = (m_h-2*Y0)%wp->font->inc_y) X { X hh -= tmp; X m_h -= tmp; X } X if (m_w>wp->wi_w) ww = ww-(m_w-wp->wi_w); X if (m_h>wp->wi_h) hh = hh-(m_h-wp->wi_h); X wind_set(wdes, WF_CURRXYWH, xx, yy, ww, hh); X wind_get(wdes, WF_WORKXYWH, &wp->x, &wp->y, &wp->w, &wp->h); X if (wp->x_off+wp->w > wp->wi_w) X { X register int inc_x = wp->font->inc_x; X flag = 1; X wp->x_off = (wp->wi_w - wp->w)/inc_x*inc_x; X } X if (wp->y_off+wp->h > wp->wi_h) X { X register int inc_y = wp->font->inc_y; X flag = 1; X wp->y_off = (wp->wi_h - wp->h)/inc_y*inc_y; X } X x1 = wp->m_off; X x2 = (wp->x - wp->x_off) & 15; X if (x1 != x2) X { X#ifdef KOPY X int top = wp->top_y; X int cnt = wp->wi_mf.wwords >> 1; X cpbmr(wp->wi_mf.ptr, x1, top, cnt, wp->wi_mf.ptr, x2, top, cnt, X wp->wi_w, wp->wi_h); X#else X int c[8]; X c[0] = x1; X c[1] = wp->top_y; /* displayed part of memory form starts here */ X c[2] = x1 + wp->wi_w - 1; X c[3] = wp->wi_h - 1 + c[1]; X c[4] = x2; X c[5] = c[1]; X c[6] = x2 + wp->wi_w - 1; X c[7] = c[3]; X vro_cpyfm(handle, 3, c, &wp->wi_mf, &wp->wi_mf); X#endif X wp->m_off = x2; X } X if (flag) X w_redraw(wdes, FM_COPY, wp->x, wp->y, wp->w, wp->h); X setvslide(wdes); X sethslide(wdes); X} X X/* X * w_top makes win the top window. X */ Xw_top(win) Xint win; X{ X int cnt; X X wind_set(win, WF_TOP, 0, 0, 0, 0); X outport = find_port(win); X outwind = win; X w[outwind].top_age = 0; X for (cnt = 1; cnt < MAX_WIND; cnt++) X if (find_port(cnt)) /* if window is in use */ X w[cnt].top_age++; X printer_mark(outwind); X} X X/* X * w_bottom finds the bottom window and puts it on top X */ Xw_bottom() X{ X int i; X int highwin, highcnt; X X highcnt = 0; X highwin = 1; X for (i = 1; i < MAX_WIND; i++) X if (w[i].top_age > highcnt) X { X highcnt = w[i].top_age; X highwin = i; X } X if (w[highwin].used) X w_top(highwin); X} X X/* X * w_hide puts the top window on the bottom. The new top window is returned. X */ Xint w_hide() X{ X int i, j; X int newtop, botwin, highcnt; X int oldtop, dum; X X wind_get(0, WF_TOP, &oldtop, &dum, &dum, &dum); X if (!oldtop) X return (0); X j = -1; X botwin = 0; X for (j = -1; ; j--) X { X newtop = botwin; X botwin = oldtop; X highcnt = 0; X for (i = 1; i < MAX_WIND; i++) X { X if (w[i].top_age > highcnt) X { X highcnt = w[i].top_age; X botwin = i; X } X } X if (botwin == oldtop) X break; X wind_set(botwin, WF_TOP, 0, 0, 0, 0); X w[botwin].top_age = j; /*top_age less than untouched windows (top_age < 0)*/ X } X for (j = 1; j < MAX_WIND; j++) X if (find_port(j)) /* if window is in use */ X w[j].top_age += MAX_WIND + 3; /* correct top_age to reflect new order */ X return(newtop ? newtop : oldtop); X} X X#define TINYX 80 X#define TINYY 70 X/* X * w_shrink saves current size and location and shrinks to standard tiny size. X * The second from the top non-shrunk window is placed on top. X */ Xw_shrink(wdes) Xint wdes; X{ X register struct wi_str *wp = &w[wdes]; X int curw, dummy; X X /* X * Don't shrink a window that is currently shrunk X */ X wind_get(wdes, WF_CURRXYWH, &dummy, &dummy, &curw, &dummy); X if (curw <= TINYX) X return; X X /* X * Set up fulled and previous size and location window variables to tiny X * size. Then call w_full X */ X wp->fulled = 1; X wp->px = scr_x + scr_w - TINYX + 2; X wp->py = scr_y + (wdes - 1) * (TINYY - 2); X wp->pw = TINYX; X wp->ph = TINYY; X if (wp->py + 10 > scr_y + scr_h) X { X wp->py = wp->py - scr_h + 10; X wp->px = scr_x + scr_w - TINYY * 2; X } X X return (w_full(wdes)); X} X X/* w_full toggles size and location X */ Xw_full(wdes) X{ X register struct wi_str *wp = &w[wdes]; X int x1, y1, w1, h1; X int x2, y2, w2, h2; X int full, topwin; X X full = wp->fulled; X if (full) { X x1 = wp->px; X y1 = wp->py; X w1 = wp->pw; X h1 = wp->ph; X } else X wind_get(wdes, WF_FULLXYWH, &x1, &y1, &w1, &h1); X X wind_get(wdes, WF_CURRXYWH, &x2, &y2, &w2, &h2); X wp->px = x2; X wp->py = y2; X wp->pw = w2; X wp->ph = h2; X if (!fast) X { X if (w2>=w1 && h2>=h1) X graf_growbox(x2, y2, w2, h2, x1, y1, w1, h1); X else if (w2<=w1 && h2<=h1) X graf_shrinkbox(x1, y1, w1, h1, x2, y2, w2, h2); X } X X x2 = wp->x_off; X y2 = wp->y_off; X wp->x_off = wp->px_off; X wp->y_off = wp->py_off; X wp->px_off = x2; X wp->py_off = y2; X X w_move(wdes, x1, y1, w1, h1); X w_redraw(wdes, FM_COPY, wp->x, wp->y, wp->w, wp->h); X wp->fulled = 1; X topwin = wdes; X if (h1 < TINYY + 10) X { X int lowcnt, i; X X lowcnt = 32000; X for (i = 1; i< MAX_WIND; i++) X { X if (find_port(i)) X { X wind_get(i, WF_CURRXYWH, &x2, &y2, &w2, &h2); X X if (w[i].top_age < lowcnt && h2 > TINYY + 10 ) X { /* find top non-tiny open window */ X lowcnt = w[i].top_age; X topwin = i; X } X } X } X wind_set(topwin, WF_TOP, 0, 0, 0, 0); X } X return(topwin); X} X Xw_arrow(wdes, arrow) X{ X register struct wi_str *wp = &w[wdes]; X int inc_x = wp->font->inc_x; X int inc_y = wp->font->inc_y; X X switch (arrow) X { X case 0: /* page up */ X wp->y_off -= wp->h/inc_y*inc_y; X goto y_upd; X X case 1: /* page down */ X wp->y_off += wp->h/inc_y*inc_y; X goto y_upd; X X case 2: /* row up */ X wp->y_off -= inc_y; X goto y_upd; X X case 3: /* row down */ X wp->y_off += inc_y; X goto y_upd; X X case 4: /* page left */ X wp->x_off -= wp->w/inc_x*inc_x; X goto x_upd; X X case 5: /* page right */ X wp->x_off += wp->w/inc_x*inc_x; X goto x_upd; X X case 6: /* column left */ X wp->x_off -= inc_x; X goto x_upd; X X case 7: /* column right */ X wp->x_off += inc_x; X goto x_upd; X } X Xx_upd: X if (wp->x_off<0) wp->x_off = 0; else X if (wp->x_off+wp->w > wp->wi_w) wp->x_off = (wp->wi_w - wp->w)/inc_x*inc_x; X sethslide(wdes); X goto upd; X Xy_upd: X if (wp->y_off<0) wp->y_off = 0; else X if (wp->y_off+wp->h > wp->wi_h) wp->y_off = (wp->wi_h - wp->h)/inc_y*inc_y; X setvslide(wdes); X Xupd: X w_redraw(wdes, FM_COPY, wp->x, wp->y, wp->w, wp->h); X} X Xw_slide(wdes, hor, val) X{ X register struct wi_str *wp = &w[wdes]; X X if (hor) X { X tmp = wp->font->inc_x; X wp->x_off = ((long)val*(wp->wi_w-wp->w)/1000)/tmp*tmp; X sethslide(wdes); X } else X { X tmp = wp->font->inc_y; X wp->y_off = ((long)val*(wp->wi_h-wp->h)/1000)/tmp*tmp; X setvslide(wdes); X } X w_redraw(wdes, FM_COPY, wp->x, wp->y, wp->w, wp->h); X} X Xsethslide(wdes) X{ X register struct wi_str *wp = &w[wdes]; X X if (wp->wi_style & HSLIDE) X { X tmp = (long)1000*wp->x_off/(wp->wi_w-wp->w); X wind_set(wdes, WF_HSLIDE, tmp, 0, 0, 0); X tmp = (long)1000*wp->w/wp->wi_w; X wind_set(wdes, WF_HSLSIZE, tmp, 0, 0, 0); X } X} X Xsetvslide(wdes) X{ X register struct wi_str *wp = &w[wdes]; X X if (wp->wi_style & VSLIDE) X { X tmp = (long)1000*wp->y_off/(wp->wi_h-wp->h); X wind_set(wdes, WF_VSLIDE, tmp, 0, 0, 0); X tmp = (long)1000*wp->h/wp->wi_h; X wind_set(wdes, WF_VSLSIZE, tmp, 0, 0, 0); X } X} X Xw_flash(wdes, state) X{ X register struct wi_str *wp = &w[wdes]; X static int wdes_last; X#ifdef KOPY X int x, y, cnt; X#else X int t[8]; X#endif X X if (wdes != wdes_last) w_flash(wdes_last, 1); X wdes_last = wdes; X if (!wp->used || wp->curstate == state) return; X if (state == 2) X wp->curstate = !wp->curstate; X else X wp->curstate = state; X#ifdef KOPY X x = wp->cur_x + wp->m_off; X y = wp->cur_y; X cnt = wp->wi_mf.wwords >> 1; X tfbmr(wp->wi_mf.ptr, x, y, cnt, wp->wi_mf.ptr, x, y, cnt, X wp->font->inc_x, wp->font->inc_y, 12); X#else X t[0] = t[4] = wp->cur_x + wp->m_off; X t[1] = t[5] = wp->cur_y; X t[2] = t[6] = t[0]+wp->font->inc_x-1; X t[3] = t[7] = t[1]+wp->font->inc_y-1; X vro_cpyfm(handle, 12, t, &wp->wi_mf, &wp->wi_mf); X#endif X w_update(wdes, FM_COPY, wp->cur_x, wp->cur_y, wp->font->inc_x, wp->font->inc_y); X} X X/* w_output prints a string onto the window. The string may X * contain control chars and escape sequences. It ends with \0. X */ X Xw_output(wdes, ptr) Xchar *ptr; X{ X register struct wi_str *wp = &w[wdes]; X static char ch; X static int inc_x, cur_x; X static int state; X static int inc_y, cur_y; X#ifdef KOPY X int x, w, cnt; X#else X static int t[8]; X#endif X static int f_x, f_y, f_mod; X static int scrolled; /* Number of scrolling operations delayed */ X static int xsiz, ysiz;/* Size in chars of terminal emulation for this window*/ X register unsigned char *sptr; X register unsigned long *dptr; X register unsigned long mask; X register int shift; X register unsigned long val; X static int count; X static char * fdata; X static long width; X static char * wimfptr; X static int moffincx; X static char * savptr; X X X#ifdef DEBUG X printf("entered w_output\n"); X#endif X if (!wp->font) return; X state = wp->state; X inc_x = wp->font->inc_x; X inc_y = wp->font->inc_y; X xsiz = wp->x_chrs; X ysiz = wp->y_chrs; X f_x = cur_x = wp->cur_x; X f_y = cur_y = wp->cur_y; X scrolled = wp->top_y/inc_y; X fdata = wp->font->f_data; X width = 2 * wp->wi_mf.wwords; X wimfptr = ((char *) (wp-> wi_mf.ptr)) - 2; X moffincx = wp->m_off + inc_x - 1; X f_mod = 0; X savptr = ptr; X X if (wp->curstate) w_flash(wdes, 0); X X while (ch = *ptr++) X { X switch (state) X { X case S_NORMAL: X if (ch >= ' ') X { X if (wp->insmode) /* open space for character */ X { X#ifdef KOPY X x = cur_x + wp->m_off; X cnt = wp->wi_mf.wwords >> 1; X cpbmr(wp->wi_mf.ptr, x, cur_y, cnt, X wp->wi_mf.ptr, x + inc_x, cur_y, cnt, X (xsiz - 1) * inc_x + wp->m_off - x, inc_y); X#else X t[0] = cur_x + wp->m_off; X t[1] = t[5] = cur_y; X t[2] = (xsiz - 1) * inc_x + wp->m_off - 1; X t[3] = t[7] = cur_y + inc_y - 1; X t[4] = t[0] + inc_x; X t[6] = t[2] + inc_x; X vro_cpyfm(handle, 3, t, &wp->wi_mf, &wp->wi_mf); X#endif X } X /* paint the character */ X sptr = fdata+ch*16; X dptr = wimfptr + cur_y*width X + (((moffincx + cur_x)>>4)<<1); X shift = 15 - ((moffincx + cur_x)&15); X if (overstrike) X mask = -1L; X else X mask = (-1L<<(shift+inc_x)|(1<<shift)-1); X if (wp->inverse) X { X for (count = inc_y; count; count--) X { X val = ((long)(*sptr++))<<shift ^ ~mask; X *dptr = (*dptr&mask)|val; X ((char *)dptr) += width; X } X } else X { X for (count = inc_y; count; count--) X { X val = ((long)(*sptr++))<<shift; X *dptr = (*dptr&mask)|val; X ((char *)dptr) += width; X } X } X cur_x += inc_x; X f_mod = 1; X if (cur_x > inc_x * xsiz) /* autowrap */ X { X cur_y += inc_y; X if (cur_y >= wp->top_y + inc_y * ysiz) { X if (wp->ptr_status & LOG_TOP) X dump_line(wdes, 0); X wp->top_y += inc_y; X ++ scrolled; X } X if (! scrolled) X { X w_update(wdes, FM_COPY, f_x, f_y, cur_x-f_x, inc_y); X f_mod = 0; X } X cur_x = X0; X X f_x = cur_x; X f_y = cur_y; X } X } else /* not printable character */ X { X if (f_mod && !scrolled) X { X if (!wp->insmode) X w_update(wdes, FM_COPY, f_x, f_y, cur_x - f_x, inc_y); X else X w_update(wdes, FM_COPY, f_x, f_y, xsiz * inc_x-f_x, inc_y); X f_mod = 0; X } X switch (ch) X { X case '\007': /* Bell */ X if (audibell) X Bconout(2, '\007'); X if (toponbel) X /* put this window on top but don't make it the current window. X * should we set a flag so that the first input from the current X * window puts it back on top? X */ X wind_set(wdes, WF_TOP, wdes, 0, 0, 0); X if (visibell) X { X w_redraw(wdes, FM_INVERT, wp->x, wp->y, wp->w, wp->h); X w_redraw(wdes, FM_COPY, wp->x, wp->y, wp->w, wp->h); X /* Should clear flag to prevent need for next update? */ X } X break; X X case '\r': /* Carriage Return */ X cur_x = X0; X break; X X case '\b': /* Backspace */ X if (cur_x>X0) cur_x -= inc_x; X break; X X case '\n': /* Newline */ X cur_y += inc_y; X if (cur_y >= inc_y * ysiz + wp->top_y) X { X if (wp->ptr_status & LOG_TOP) X dump_line(wdes, 0); X wp->top_y += inc_y; SHAR_EOF echo "End of part 4, continue with part 5" echo "5" > s2_seq_.tmp exit 0