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