Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

v09i059: Terminal emulator for X window system, Part06/07

9 views
Skip to first unread message

sources...@mirror.tmc.com

unread,
Apr 21, 1987, 2:25:54 PM4/21/87
to
Submitted by: ed...@opal.Berkeley.EDU
Mod.sources: Volume 9, Issue 59
Archive-name: xterm6.6b/Part06

#! /bin/sh
# This is a shell archive, meaning:
# 1. Remove everything above the #! /bin/sh line.
# 2. Save the resulting text in a file.
# 3. Execute the file with /bin/sh (not csh) to create the files:
# input.c menu.h misc.c resize.c screen.c
if test -f input.c
then
echo shar: will not overwrite existing file "'input.c'"
else
echo 'x - input.c'
cat << \RAZZLE!DAZZLE > input.c
/*
* $Source: /u1/X/xterm/RCS/input.c,v $
* $Header: input.c,v 10.100 86/12/01 14:44:04 jg Rel $
*/

#ifndef lint
static char *rcsid_input_c = "$Header: input.c,v 10.100 86/12/01 14:44:04 jg Rel $";
#endif lint

#include <X/mit-copyright.h>

/* Copyright Massachusetts Institute of Technology 1984, 1985 */

/* input.c */

#ifndef lint
static char sccs_id[] = "@(#)input.c\tX10/6.6B\t12/26/86";
#endif lint

#include <X/Xlib.h>
#include <X/Xkeyboard.h>
#include "scrollbar.h"
#include "ptyx.h"
#include <stdio.h>

static char *kypd_num = "0x.\r123456,789-";
static char *kypd_apl = "pxnMqrstuvlwxym";
static char *cur = "DCBA";

Input (keyboard, screen, event)
register Keyboard *keyboard;
register Screen *screen;
register XKeyPressedEvent *event;
{
register int keycode = event->detail;
register char *string;
register int col, key = FALSE;
int pty = screen->respond;
int nbytes;
ANSI reply;

string = XLookupMapping (event, &nbytes);

if (nbytes > 0) {
if(screen->TekGIN) {
TekEnqMouse(*string++);
TekGINoff();
nbytes--;
}
while (nbytes-- > 0)
unparseputc(*string++, pty);
key = TRUE;
} else {
keycode &= ValueMask; /* no longer need shift bits for anything */
reply.a_pintro = 0;
reply.a_final = 0;
reply.a_nparam = 0;
reply.a_inters = 0;
if (IsKeypadKey(keycode)) {
if (keyboard->flags & KYPD_APL) {
reply.a_type = SS3;
unparseseq(&reply, pty);
unparseputc(kypd_apl[keycode-KC_KEYPAD_0], pty);
} else
unparseputc(kypd_num[keycode-KC_KEYPAD_0], pty);
key = TRUE;
} else if (IsCursorKey(keycode)) {
if (keyboard->flags & CURSOR_APL) {
reply.a_type = SS3;
unparseseq(&reply, pty);
unparseputc(cur[keycode-KC_CURSOR_LEFT], pty);
} else {
reply.a_type = CSI;
reply.a_final = cur[keycode-KC_CURSOR_LEFT];
unparseseq(&reply, pty);
}
key = TRUE;
} else if (IsPFKey(keycode)) {
reply.a_type = SS3;
unparseseq(&reply, pty);
unparseputc((char)(keycode-KC_PF1+'P'), pty);
key = TRUE;
} else if (IsFunctionKey(keycode)) {
reply.a_type = CSI;
reply.a_nparam = 1;
reply.a_param[0] = funcvalue(keycode);
reply.a_final = '~';
if (reply.a_param[0] > 0)
unparseseq(&reply, pty);
key = TRUE;
}
}
if(key && !screen->TekEmu) {
if(screen->scrollkey && screen->topline != 0)
ScrollToBottom(screen->sb);
if(screen->marginbell) {
col = screen->max_col - screen->nmarginbell;
if(screen->bellarmed >= 0) {
if(screen->bellarmed == screen->cur_row) {
if(screen->cur_col >= col) {
if(screen->cur_col == col)
Bell();
screen->bellarmed = -1;
}
} else
screen->bellarmed = screen->cur_col <
col ? screen->cur_row : -1;
} else if(screen->cur_col < col)
screen->bellarmed = screen->cur_row;
}
}
#ifdef ENABLE_PRINT
if (keycode == KC_F2) TekPrint();
#endif
return;
}

funcvalue(keycode)
{
switch (keycode) {
case KC_F1: return(11);
case KC_F2: return(12);
case KC_F3: return(13);
case KC_F4: return(14);
case KC_F5: return(15);
case KC_F6: return(17);
case KC_F7: return(18);
case KC_F8: return(19);
case KC_F9: return(20);
case KC_F10: return(21);
case KC_F11: return(23);
case KC_F12: return(24);
case KC_F13: return(25);
case KC_F14: return(26);
case KC_F15: return(28);
case KC_F16: return(29);
case KC_F17: return(31);
case KC_F18: return(32);
case KC_F19: return(33);
case KC_F20: return(34);
case KC_E1 : return(1);
case KC_E2: return(2);
case KC_E3: return(3);
case KC_E4: return(4);
case KC_E5: return(5);
case KC_E6: return(6);
default: return(-1);
}
}
RAZZLE!DAZZLE
fi # End input.c
if test -f menu.h
then
echo shar: will not overwrite existing file "'menu.h'"
else
echo 'x - menu.h'
cat << \RAZZLE!DAZZLE > menu.h
/*
* $Source: /u1/X/xterm/RCS/menu.h,v $
* $Header: menu.h,v 10.100 86/12/01 14:40:05 jg Rel $
*/

/* @(#)menu.h X10/6.6B 12/26/86 */
/*
* Menu items are constructed as follows, starting from the left side:
*
* menuItemPad
* space for check mark
* menuItemPad
* text + padding
* menuItemPad
*
* The padding for the text is that amount that this text is narrower than the
* widest text.
*/

typedef struct _menuItem {
int itemHeight; /* total height of this item */
int itemFlags; /* flags of item */

#define itemDisabled 0x0001 /* item is disabled */
#define itemChecked 0x0002 /* item has check mark */
#define itemStateMask 0x0003 /* mask for current state */
#define itemSetDisabled 0x0004 /* item wants to be disabled */
#define itemSetChecked 0x0008 /* item wants check mark */
#define itemSetMask 0x000c /* mask for desired state */
#define itemSetMaskShift 2 /* for comparison with actual */
#define itemChanged 0x0010 /* item desires change */

char *itemText; /* text of item */
int itemTextWidth; /* width of text */
int itemTextLength; /* length of text */
struct _menuItem *nextItem; /* next item in chain */
} MenuItem;

typedef struct _menu {
int menuWidth; /* full width of menu */
int menuHeight; /* full height of menu */
int menuFlags; /* flags of this menu */

# define menuChanged 0x0001 /* menu changed, must redraw */
# define menuItemChanged 0x0002 /* item changed, must redraw */
# define menuMapped 0x0004 /* menu is now mapped */
# define menuFreeze 0x0008 /* freeze when doing menu */
# define menuSaveMenu 0x0010 /* save copy of menu */

int menuMaxTextWidth; /* width of widest text */
int menuInitialItem; /* < 0 none, >= 0 initial item */
int menuBorderWidth; /* width of border */
int menuBgColor; /* background color */
int menuFgColor; /* foreground color */
Pixmap menuBgTile; /* backgroud tile */
FontInfo *menuFontInfo; /* fontinfo for menu font */
int menuItemPad; /* pad amount */
Window menuWindow; /* window of menu */
int (*menuEventHandler)(); /* external event handler */
Cursor menuCursor; /* cursor used in menu */
Pixmap menuSaved; /* copy of menu */
Pixmap menuSavedImage; /* copy of image under menu */
int menuSavedImageX; /* X coordinate of the saved image */
int menuSavedImageY; /* Y coordinate of the saved image */
MenuItem *menuItems; /* head of menu item chain */
char *menuTitle; /* title of menu */
int menuTitleWidth; /* width of title */
int menuTitleLength; /* length of title */
int menuItemTop; /* position of top of first item */
} Menu;

#define checkMarkWidth 9
#define checkMarkHeight 8
#define defaultCursorWidth 16
#define defaultCursorHeight 16
#define defaultCursorX 1
#define defaultCursorY 1
#define grayHeight 16
#define grayWidth 16
#define lineSeparatorHeight 9

#define CheckItem(menu,item) SetItemCheck(menu,item,1)
#define DisableItem(menu,item) SetItemDisable(menu,item,1)
#define EnableItem(menu,item) SetItemDisable(menu,item,0)
#define SetMenuEventHandler(menu,f) menu->menuEventHandler = f
#define UncheckItem(menu,item) SetItemCheck(menu,item,0)

extern Menu *NewMenu();
RAZZLE!DAZZLE
fi # End menu.h
if test -f misc.c
then
echo shar: will not overwrite existing file "'misc.c'"
else
echo 'x - misc.c'
cat << \RAZZLE!DAZZLE > misc.c
/*
* $Source: /u1/X/xterm/RCS/misc.c,v $
* $Header: misc.c,v 10.101 86/12/02 08:49:20 swick Exp $
*/

#include <stdio.h>
#include <setjmp.h>
#include <signal.h>
#include <ctype.h>
#include <pwd.h>
#include <sys/time.h>
#include <sys/file.h>
#include <X/Xlib.h>
#include "scrollbar.h"
#include "ptyx.h"
#include "data.h"
#include "error.h"
#include "gray.ic"
#include "hilite.ic"
#include "icon.ic"
#include "tek_icon.ic"
#include "wait.ic"
#include "waitmask.ic"
#include "../cursors/left_ptr.cursor"
#include "../cursors/left_ptr_mask.cursor"
#include "../cursors/tcross.cursor"
#include "../cursors/tcross_mask.cursor"
#include "../cursors/xterm.cursor"
#include "../cursors/xterm_mask.cursor"

#ifndef lint
static char sccs_id[] = "@(#)misc.c\tX10/6.6B\t1/9/87";
#endif lint

xevents()
{
XEvent reply;
register XEvent *rep = & reply;
register Screen *screen = &term.screen;

if(screen->scroll_amt)
FlushScroll(screen);
XPending ();
do {
XNextEvent (&reply);
xeventpass(&reply);
} while (QLength() > 0);
}

xeventpass(rep)
register XEvent *rep;
{
register Screen *screen = &term.screen;
register Window window = rep->window;
register Window w;
register int i;

switch ((int)rep->type) {
case KeyPressed:
Input (&term.keyboard, &term.screen,
(XKeyPressedEvent *)rep);
break;

case ExposeWindow:
if(screen->sb && window == screen->sb->bar) {
#ifdef DEBUG
if(debug)
fputs("ExposeWindow scrollbar\n", stderr);
#endif DEBUG
if(((XExposeEvent *)rep)->subwindow ==
screen->sb->button) {
screen->sb->buttonstate = -1;
DrawButton(screen->sb);
} else if(((XExposeEvent *)rep)->subwindow ==
screen->sb->save) {
screen->sb->savestate = -1;
DrawSave(screen->sb);
}
break;
}
if (screen->active_icon) {
#ifdef DEBUG
fputs( "ExposeWindow icon\n", stderr );
#endif DEBUG
if (window == screen->iconVwin.window) {
if (!screen->icon_show) {
screen->mappedVwin = &screen->iconVwin;
screen->icon_show = TRUE;
screen->show = FALSE;
screen->timer = 0;
screen->holdoff = FALSE;
if(screen->fullTwin.window)
moveiconwindow( screen->fullTwin.window,
screen->fullVwin.window );
}
if (screen->TekEmu)
VTUnselect();
if (term.flags & ICONINPUT)
reselectwindow(screen);
else
unselectwindow(screen, INWINDOW);
screen->iconinput = FALSE;
VTExpose(rep);
} else if (window == screen->iconTwin.window) {
if (!screen->icon_show) {
screen->mappedTwin = &screen->iconTwin;
screen->icon_show = TRUE;
screen->Tshow = FALSE;
screen->timer = 0;
screen->holdoff = FALSE;
if (screen->fullVwin.window)
moveiconwindow( screen->fullVwin.window,
screen->fullTwin.window );
}
if (!screen->TekEmu)
TekUnselect();
if (term.flags & ICONINPUT)
reselectwindow(screen);
else
unselectwindow(screen, INWINDOW);
screen->iconinput = FALSE;
TekExpose(rep);
}
} else if (window == screen->iconVwin.window ||
window == screen->iconTwin.window) {
#ifdef DEBUG
if(debug)
fprintf(stderr, "ExposeWindow %s\n", window ==
screen->iconVwin.window ? "icon" : "Ticon");
#endif DEBUG
RefreshIcon(screen, window);
break;
}
if(Titlebar(screen) || screen->icon_show) {
/* icon_show is a kludge as the titlebar exposure event
* frequently arrives before the full window exposure event */
if(window == screen->title.tbar) {
#ifdef DEBUG
if(debug)
fputs("ExposeWindow title\n", stderr);
#endif DEBUG
VTTitleExpose((XExposeWindowEvent *)rep);
break;
} else if(window == screen->Ttitle.tbar) {
#ifdef DEBUG
if(debug)
fputs("ExposeWindow Ttitle\n", stderr);
#endif DEBUG
TekTitleExpose((XExposeWindowEvent *)rep);
break;
}
}
if(window == screen->fullVwin.window) {
#ifdef DEBUG
if(debug)
fputs("ExposeWindow VT\n", stderr);
#endif DEBUG
if(!screen->show) {
screen->mappedVwin = &screen->fullVwin;
if(screen->Ticonunmap) {
screen->Ticonunmap = FALSE;
XMapWindow( screen->fullTwin.window );
screen->Tshow = TRUE;
if(!screen->TekEmu) {
screen->holdoff = TRUE;
XUnmapTransparent(VWindow(screen));
XMapWindow(VWindow(screen));
break;
}
} else {
screen->timer = 0;
screen->holdoff = FALSE;
}
screen->show = TRUE;
reselectwindow(screen);
if(screen->icon_show && screen->deiconwarp)
DeiconWarp(screen);

screen->icon_show = FALSE;
screen->iconinput = FALSE;
}
VTExpose(rep);
} else if(window == screen->fullTwin.window) {
#ifdef DEBUG
if(debug)
fputs("ExposeWindow Tek\n", stderr);
#endif DEBUG
if(!screen->Tshow) {
screen->mappedTwin = &screen->fullTwin;
if(screen->iconunmap) {
screen->iconunmap = FALSE;
XMapWindow( screen->fullVwin.window );
screen->show = TRUE;
if(screen->TekEmu) {
screen->holdoff = TRUE;
XUnmapTransparent(TWindow(screen));
XMapWindow(TWindow(screen));
break;
}
} else {
screen->timer = 0;
screen->holdoff = FALSE;
}
screen->Tshow = TRUE;
reselectwindow(screen);
if(screen->icon_show && screen->deiconwarp)
DeiconWarp(screen);
screen->icon_show = FALSE;
screen->iconinput = FALSE;
}
TekExpose(rep);
}
break;

case ExposeRegion:
if (!screen->active_icon && window == screen->iconVwin.window ||
window == screen->iconTwin.window) {
#ifdef DEBUG
if(debug)
fprintf(stderr, "ExposeRegion %s\n", window ==
screen->iconVwin.window ? "icon" : "Ticon");
#endif DEBUG
RefreshIcon(screen, window);
break;
}
#ifdef DEBUG
if(debug)
fputs("ExposeRegion\n", stderr);
#endif DEBUG
if (((XExposeWindowEvent *)rep)->detail == ExposeCopy &&
screen->incopy <= 0) {
screen->incopy = 1;
if (screen->scrolls > 0)
screen->scrolls--;
}
if (HandleExposure (screen, rep))
screen->cursor_state = OFF;
break;

case ExposeCopy:
#ifdef DEBUG
if(debug)
fputs("ExposeCopy\n", stderr);
#endif DEBUG
if (screen->incopy <= 0 && screen->scrolls > 0)
screen->scrolls--;
if (screen->scrolls)
screen->incopy = -1;
else
screen->incopy = 0;
break;

case ButtonPressed:
if (screen->incopy)
CopyWait (screen);
if(window == screen->iconVwin.window) {
#ifdef DEBUG
if(debug)
fputs("ButtonPressed icon\n", stderr);
#endif DEBUG
XUnmapWindow(window);
if(screen->Ticonunmap && !screen->TekEmu) {
screen->Ticonunmap = FALSE;
XMapWindow(TWindow(screen));
screen->Tshow = TRUE;
screen->holdoff = TRUE;
}
XMapWindow(screen->fullVwin.window);
break;
} else if(window == screen->iconTwin.window) {
#ifdef DEBUG
if(debug)
fputs("ButtonPressed Ticon\n", stderr);
#endif DEBUG
XUnmapWindow(window);
if(screen->iconunmap && screen->TekEmu) {
screen->iconunmap = FALSE;
XMapWindow(VWindow(screen));
screen->show = TRUE;
screen->holdoff = TRUE;
}
XMapWindow(screen->fullTwin.window);
break;
}
/* drop through */
case ButtonReleased:
#ifdef DEBUG
if(debug)
fputs("ButtonPressed or ButtonReleased\n",
stderr);
#endif DEBUG
HandleButtons(&term, rep, screen->respond);
break;

case UnmapWindow: /* full windows */
if (window == screen->fullVwin.window) {
#ifdef DEBUG
if(debug)
fputs("UnmapWindow VT\n", stderr);
#endif DEBUG
if (screen->fullVwin.titlebar)
VTTitleUnhilite();
screen->show = FALSE;
if(screen->Tshow) {
screen->Ticonunmap = TRUE;
screen->Tshow = FALSE;
XUnmapWindow( screen->fullTwin.window );
SyncUnmap( screen->fullTwin.window,
TWINDOWEVENTS );
}
} else if(window == screen->fullTwin.window) {
#ifdef DEBUG
if(debug)
fputs("UnmapWindow Tek\n", stderr);
#endif DEBUG
if (screen->fullTwin.titlebar)
TekTitleUnhilite();
screen->Tshow = FALSE;
if(screen->show) {
screen->iconunmap = TRUE;
screen->show = FALSE;
XUnmapWindow( screen->fullVwin.window );
SyncUnmap( screen->fullVwin.window,
WINDOWEVENTS );
}
}
reselectwindow(screen);
screen->timer = 0;
break;
case EnterWindow:
if(screen->sb) {
if(window == screen->sb->button) {
if((i = GetButtonState(screen->sb)) !=
BUTTON_NORMAL)
SetButtonState(screen->sb, i | HILITED);
break;
} else if(window == screen->sb->bar)
break;
}
if((window == VWindow(screen) || window == TWindow(screen)) &&
(((XEnterWindowEvent *)rep)->detail & 0xff) !=
IntoOrFromSubwindow) {
#ifdef DEBUG
if(debug)
fprintf(stderr, "EnterWindow %s\n", window ==
VWindow(screen) ? "VT" : "Tek");
#endif DEBUG
screen->autowindow = window;
DoEnterLeave(screen, EnterWindow);
}
break;
case LeaveWindow:
if(screen->sb) {
if(window == screen->sb->button) {
if((i = GetButtonState(screen->sb)) !=
BUTTON_NORMAL)
SetButtonState(screen->sb, i& ~HILITED);
break;
} else if(window == screen->sb->bar)
break;
}
if((window == VWindow(screen) || window == TWindow(screen)) &&
(((XEnterWindowEvent *)rep)->detail & 0xff) !=
IntoOrFromSubwindow)
#ifdef DEBUG
{
if(debug)
fprintf(stderr, "LeaveWindow %s\n", window ==
VWindow(screen) ? "VT" : "Tek");
#endif DEBUG
DoEnterLeave(screen, LeaveWindow);
#ifdef DEBUG
}
#endif DEBUG
break;
case FocusChange:
if(((XFocusChangeEvent *)rep)->detail == EnterWindow)
selectwindow(screen, FOCUS);
else
unselectwindow(screen, FOCUS);
break;
default:
break;
}
}

selectwindow(screen, flag)
register Screen *screen;
register int flag;
{
if(screen->TekEmu) {
TekSelect();
if(!Ttoggled)
TCursorToggle(TOGGLE);
if(screen->cellsused) {
screen->colorcells[2].pixel =
screen->Tcursorcolor;
XStoreColor(&screen->colorcells[2]);
}
screen->select |= flag;
if(!Ttoggled)
TCursorToggle(TOGGLE);
return;
} else {
VTSelect();
if(screen->cursor_state &&
(screen->cursor_col != screen->cur_col ||
screen->cursor_row != screen->cur_row))
HideCursor();
screen->select |= flag;
if(screen->cursor_state)
ShowCursor();
return;
}
}

unselectwindow(screen, flag)
register Screen *screen;
register int flag;
{
register int i;

screen->select &= ~flag;
if(!screen->select) {
if(screen->TekEmu) {
TekUnselect();
if(!Ttoggled)
TCursorToggle(TOGGLE);
if(screen->cellsused) {
i = (term.flags & REVERSE_VIDEO) == 0;
screen->colorcells[i].pixel =
screen->Tcursorcolor;
XStoreColor(
&screen->colorcells[i]);
}
if(!Ttoggled)
TCursorToggle(TOGGLE);
return;
} else {
VTUnselect();
if(screen->cursor_state &&
(screen->cursor_col != screen->cur_col ||
screen->cursor_row != screen->cur_row))
HideCursor();
if(screen->cursor_state)
ShowCursor();
return;
}
}
}

reselectwindow(screen)
register Screen *screen;
{
Window win;
int x, y;

if(XQueryMouse(RootWindow, &x, &y, &win)) {
if(win && (win == VWindow(screen) || win == TWindow(screen))
&& (!screen->icon_show
|| (screen->active_icon && term.flags & ICONINPUT)))
selectwindow(screen, INWINDOW);
else unselectwindow(screen, INWINDOW);
}
}

DeiconWarp(screen)
register Screen *screen;
{
if(screen->TekEmu)
XWarpMouse(TWindow(screen), TFullWidth(screen) / 2,
TFullHeight(screen) / 2);
else
XWarpMouse(VWindow(screen), FullWidth(screen) / 2,
FullHeight(screen) / 2);
}

#define ENTERLEAVE 500000L

DoEnterLeave(screen, type)
register Screen *screen;
int type;
{
if (!screen->autoraise && !screen->holdoff) {
if (type == EnterWindow)
selectwindow( screen, INWINDOW );
else unselectwindow( screen, INWINDOW );
return;
}

screen->timer = type;
if(!screen->holdoff)
Timer(ENTERLEAVE);
}

Timer(val)
long val;
{
struct itimerval it;

bzero(&it, sizeof(it));
it.it_value.tv_usec = val;
setitimer(ITIMER_REAL, &it, (struct itimerval *)0);
}

onalarm()
{
register Screen *screen = &term.screen;

if(screen->timer == 0 || screen->holdoff) { /* extraneous alarm */
Timer(0L);
return;
}
if(screen->timer == EnterWindow) {
#ifdef DEBUG
if(debug)
fprintf(stderr, "onalarm: EnterWindow %s\n",
screen->autoraise ? (screen->autowindow ==
VWindow(screen) ? "VT" : "Tek") : "");
#endif DEBUG
selectwindow(screen, INWINDOW);
if(screen->autoraise)
XRaiseWindow(screen->autowindow);
} else /* LeaveWindow */
#ifdef DEBUG
{
if(debug)
fputs("onalarm: LeaveWindow\n", stderr);
#endif DEBUG
unselectwindow(screen, INWINDOW);
#ifdef DEBUG
}
#endif DEBUG
screen->timer = 0;
}

Pixmap make_hilite(fg, bg)
int fg, bg;
{
extern Pixmap Make_tile();

return(Make_tile(hilite_width, hilite_height, hilite_bits, fg,
bg));
}

Pixmap make_gray()
{
extern Pixmap Make_tile();

return(Make_tile(gray_width, gray_height, gray_bits, BlackPixel,
WhitePixel));
}

Cursor make_tcross(fg, bg, func)
int fg, bg, func;
{
return(XCreateCursor(tcross_width, tcross_height, tcross_bits,
tcross_mask_bits, tcross_x_hot, tcross_y_hot, fg, bg, func));
}

Cursor make_xterm(fg, bg, func)
int fg, bg, func;
{
return(XCreateCursor(xterm_width, xterm_height, xterm_bits,
xterm_mask_bits, xterm_x_hot, xterm_y_hot, fg, bg, func));
}

Cursor make_wait(fg, bg, func)
int fg, bg, func;
{
return(XCreateCursor(wait_width, wait_height, wait_bits, waitmask_bits,
wait_x_hot, wait_y_hot, fg, bg, func));
}

Cursor make_arrow(fg, bg, func)
int fg, bg, func;
{
return(XCreateCursor(left_ptr_width, left_ptr_height, left_ptr_bits,
left_ptr_mask_bits, left_ptr_x_hot, left_ptr_y_hot, fg, bg, func));
}

char *uniquesuffix(name)
char *name;
{
register int *np, *fp, i;
register Window *cp;
register int temp, j, k, exact, *number;
char *wname;
Window *children, parent;
int nchildren;
static char *suffix, sufbuf[10];
char *malloc();

if(suffix)
return(suffix);
suffix = sufbuf;
if(!XQueryTree(RootWindow, &parent, &nchildren, &children) ||
nchildren < 1 || (number = (int *)malloc(nchildren * sizeof(int)))
== NULL)
return(suffix);
exact = FALSE;
i = strlen(name);
for(np = number, cp = children, j = nchildren ; j > 0 ; cp++, j--) {
if(!XFetchName(*cp, &wname) || wname == NULL)
continue;
if(strncmp(name, wname, i) == 0) {
if(wname[i] == 0 || strcmp(&wname[i], " (Tek)") == 0)
exact = TRUE;
else if(strncmp(&wname[i], " #", 2) == 0)
*np++ = atoi(&wname[i + 2]);
}
free(wname);
}
free((char *)children);
if(exact) {
if(np <= number)
strcpy(suffix, " #2");
else {
exact = np - number;
np = number;
/* shell sort */
for(i = exact / 2 ; i > 0 ; i /= 2)
for(k = i ; k < exact ; k++)
for(j = k - i ; j >= 0 &&
np[j] > np[j + i] ; j -= i) {
temp = np[j];
np[j] = np[j + i];
np[j + i] = temp;
}
/* make numbers unique */
for(fp = np + 1, i = exact - 1 ; i > 0 ; fp++, i--)
if(*fp != *np)
*++np = *fp;
/* find least unique number */
for(i = 2, fp = number ; fp <= np ; fp++) {
if(i < *fp)
break;
if(i == *fp)
i++;
}
sprintf(suffix, " #%d", i);
}
}
free((char *)number);
return(suffix);
}

Bell()
{
extern Terminal term;
register Screen *screen = &term.screen;

if(screen->visualbell) {
if(screen->TekEmu) {
if(screen->icon_show && !screen->active_icon) {
XPixSet(screen->iconTwin.window, 0, 0,
screen->iconTwin.width, screen->iconTwin.height,
screen->foreground);
XFlush();
XClear(screen->iconTwin.window);
RefreshIcon(screen, screen->iconTwin.window);
} else {
XPixFill(TWindow(screen), 0, 0,
TFullWidth(screen), TFullHeight(screen),
screen->foreground, (Bitmap)0, GXinvert,
screen->xorplane);
XFlush();
XPixFill(TWindow(screen), 0, 0,
TFullWidth(screen), TFullHeight(screen),
screen->foreground, (Bitmap)0, GXinvert,
screen->xorplane);
}
} else {
if(screen->icon_show && !screen->active_icon) {
XPixSet(screen->iconVwin.window, 0, 0,
screen->iconVwin.width, screen->iconVwin.height,
screen->foreground);
XFlush();
XClear(screen->iconVwin.window);
RefreshIcon(screen, screen->iconVwin.window);
} else {
XPixSet(VWindow(screen), 0, 0, FullWidth(screen),
FullHeight(screen), screen->foreground);
XFlush();
XClear(VWindow(screen));
ScrnRefresh(screen, 0, 0, screen->max_row + 1 +
screen->statusline, screen->max_col + 1);
}
}
} else
XFeep(0);
}

Redraw()
{
extern Terminal term;
register Screen *screen = &term.screen;

if(VWindow(screen) && screen->show) {
VTExpose(NULL);
if(screen->scrollbar) {
XClear(screen->sb->bar);
XClear(screen->sb->region);
screen->sb->buttonstate = -1;
DrawButton(screen->sb);
screen->sb->savestate = -1;
DrawSave(screen->sb);
}
if(Titlebar(screen)) {
XClear(screen->title.tbar);
XClear(screen->title.left);
XClear(screen->title.right);
VTTitleExpose(NULL);
}
}
if(TWindow(screen) && screen->Tshow) {
TekExpose(NULL);
if(Titlebar(screen)) {
XClear(screen->Ttitle.tbar);
XClear(screen->Ttitle.left);
XClear(screen->Ttitle.right);
TekTitleExpose(NULL);
}
}
}

IconInit(screen, bm, Tbm)
register Screen *screen;
char *bm, *Tbm;
{
register int w;

if(!bm && !Tbm) { /* use default bitmaps */
screen->iconbitmap.bits = icon_bits;
screen->Ticonbitmap.bits = tek_icon_bits;
screen->bitmapwidth = screen->iconbitmap.width =
screen->Ticonbitmap.width = icon_width;
screen->bitmapheight = screen->iconbitmap.height =
screen->Ticonbitmap.height = icon_height;
} else if(bm && !*bm && Tbm && !*Tbm) /* both empty means no bitmap */
screen->bitmapwidth = screen->bitmapheight = 0;
else { /* user defined bitmap(s) */
if(bm && *bm) {
if((w = XReadBitmapFile(bm, &screen->iconbitmap.width,
&screen->iconbitmap.height, &screen->iconbitmap.bits,
NULL, NULL)) == 0) {
openerror:
fprintf(stderr, "%s: Can't open %s\n",
xterm_name, bm);
Exit(ERROR_OPENBITMAP);
} else if(w < 0) {
syntaxerror:
fprintf(stderr, "%s: Syntax error in %s\n",
xterm_name, bm);
Exit(ERROR_SYNTAXBITMAP);
}
screen->bitmapwidth = screen->iconbitmap.width;
screen->bitmapheight = screen->iconbitmap.height;
}
if(Tbm && *Tbm) {
if((w = XReadBitmapFile(Tbm, &screen->Ticonbitmap.width,
&screen->Ticonbitmap.height, &screen->Ticonbitmap.bits,
NULL, NULL)) == 0)
goto openerror;
else if(w < 0)
goto syntaxerror;
if(screen->bitmapwidth < screen->Ticonbitmap.width)
screen->bitmapwidth = screen->Ticonbitmap.width;
if(screen->bitmapheight < screen->Ticonbitmap.height)
screen->bitmapheight =
screen->Ticonbitmap.height;
}
if(!screen->iconbitmap.bits) {
if(!screen->Ticonbitmap.bits) {
screen->Ticonbitmap.bits = tek_icon_bits;
screen->bitmapwidth = screen->Ticonbitmap.width
= icon_width;
screen->bitmapheight =
screen->Ticonbitmap.height = icon_height;
}
screen->iconbitmap.bits = screen->Ticonbitmap.bits;
screen->iconbitmap.width = screen->Ticonbitmap.width;
screen->iconbitmap.height = screen->Ticonbitmap.height;
} else if(!screen->Ticonbitmap.bits) {
if(!screen->iconbitmap.bits) {
screen->iconbitmap.bits = icon_bits;
screen->bitmapwidth = screen->iconbitmap.width
= icon_width;
screen->bitmapheight =
screen->iconbitmap.height = icon_height;
}
screen->Ticonbitmap.bits = screen->iconbitmap.bits;
screen->Ticonbitmap.width = screen->iconbitmap.width;
screen->Ticonbitmap.height = screen->iconbitmap.height;
}
}
if((screen->winname = malloc(strlen(win_name) + 10)) == NULL)
Error(ERROR_WINNAME);
strcpy(screen->winname, win_name);
strcat(screen->winname, uniquesuffix(win_name));
screen->winnamelen = strlen(screen->winname);
IconRecalc(screen);
}

IconRecalc(screen)
register Screen *screen;
{
register int i, w;

if (screen->active_icon) return;

w = XQueryWidth(screen->winname, screen->titlefont->id);
if(screen->bitmapwidth > 0) {
if(screen->textundericon) {
screen->icon_text_x = TITLEPAD;
screen->icon_text_y = screen->bitmapheight +
2 * TITLEPAD;
screen->iconVwin.height = screen->bitmapheight +
screen->titlefont->height + 3 * TITLEPAD;
screen->iconbitmap.x = screen->Ticonbitmap.x =
screen->iconbitmap.y = screen->Ticonbitmap.y =
TITLEPAD;
if((i = screen->bitmapwidth - w) >= 0) {
screen->iconVwin.width = screen->bitmapwidth +
2 * TITLEPAD;
screen->icon_text_x += i / 2;
} else {
screen->iconVwin.width = w + 2 * TITLEPAD;
i = (-i) / 2;
screen->iconbitmap.x += i;
screen->Ticonbitmap.x += i;
}
} else {
screen->icon_text_x = screen->bitmapwidth +
2 * TITLEPAD;
screen->icon_text_y = TITLEPAD;
screen->iconVwin.width = w + screen->bitmapwidth +
3 * TITLEPAD;
screen->iconbitmap.x = screen->Ticonbitmap.x =
screen->iconbitmap.y = screen->Ticonbitmap.y =
TITLEPAD;
if((i = screen->bitmapheight -
screen->titlefont->height) >= 0) {
screen->iconVwin.height = screen->bitmapheight +
2 * TITLEPAD;
screen->icon_text_y += i / 2;
} else {
screen->iconVwin.height = screen->titlefont->height
+ 2 * TITLEPAD;
i = (-i) / 2;
screen->iconbitmap.y += i;
screen->Ticonbitmap.y += i;
}
}
if((i = screen->iconbitmap.width - screen->Ticonbitmap.width)
>= 0)
screen->Ticonbitmap.x += i / 2;
else
screen->iconbitmap.x += (-i) / 2;
if((i = screen->iconbitmap.height - screen->Ticonbitmap.height)
>= 0)
screen->Ticonbitmap.y += i / 2;
else
screen->iconbitmap.y += (-i) / 2;
} else {
screen->icon_text_x = TITLEPAD;
screen->iconVwin.width = w + 2 * TITLEPAD;
screen->iconVwin.height = screen->titlefont->height + 2 * TITLEPAD;
}

if (screen->iconVwin.window)
XChangeWindow( screen->iconVwin.window, screen->iconVwin.width,
screen->iconVwin.height );

if (screen->iconTwin.window) {
screen->iconTwin.width = screen->iconVwin.width;
screen->iconTwin.height = screen->iconVwin.height;
XChangeWindow( screen->iconTwin.window, screen->iconTwin.width,
screen->iconTwin.height );
}

icon_box[0].x = screen->icon_text_x - 2;
icon_box[0].y = screen->icon_text_y - 2;
icon_box[3].x = -(icon_box[1].x = w + 3);
icon_box[4].y = -(icon_box[2].y = screen->titlefont->height + 3);
}

RefreshIcon(screen, window)
register Screen *screen;
Window window;
{
register BitmapBits *bb;
register int fg, bg;

bb = screen->TekEmu ? &screen->Ticonbitmap : &screen->iconbitmap;
fg = screen->foreground;
bg = screen->background;
if(screen->bitmapwidth > 0)
XBitmapBitsPut(window, bb->x, bb->y, bb->width, bb->height,
bb->bits, fg, bg, (Bitmap)0, GXcopy, AllPlanes);
XText(window, screen->icon_text_x, screen->icon_text_y,
screen->winname, screen->winnamelen, screen->titlefont->id, fg, bg);
screen->icon_show = TRUE;
if(screen->iconinput)
IconBox(screen);
}

IconBox(screen)
register Screen *screen;
{
if (screen->active_icon) return;

XDraw(screen->TekEmu ? screen->iconTwin.window : screen->iconVwin.window,
icon_box, NBOX, 1, 1, screen->foreground, GXcopy, AllPlanes);
}

/*
* Move win1's icon window to where win2's icon window is.
*/
moveiconwindow(win1, win2)
register Window win1, win2;
{
WindowInfo wininfo1, wininfo2;

XQueryWindow(win1, &wininfo1);
XQueryWindow(win2, &wininfo2);
if(wininfo1.assoc_wind && wininfo2.assoc_wind) {
XQueryWindow(wininfo2.assoc_wind, &wininfo2);
XMoveWindow(wininfo1.assoc_wind, wininfo2.x, wininfo2.y);
}
}

IconGeometry(screen, ix, iy)
register Screen *screen;
register int *ix, *iy;
{
register int i;
int w, h;

if(icon_geom) {
i = XParseGeometry(icon_geom, ix, iy, &w, &h);
/*
* XParseGeometry returns negative values in addition to
* setting the bitmask.
*/
if((i & XValue) && (i & XNegative))
*ix = DisplayWidth() + *ix - screen->iconVwin.width - 2 *
screen->borderwidth;
if((i & YValue) && (i & YNegative))
*iy = DisplayHeight() + *iy - screen->iconVwin.height - 2 *
screen->borderwidth;
}
}

InTitle(screen, window, x)
register Screen *screen;
Window window;
int x;
{
register int i, j;

if(window == screen->title.tbar) {
i = (j = FullWidth(screen) / 2) - (screen->title.x -
screen->title_n_size);
j = x - j;
if(j < 0)
j = -j;
if(j < i) {
XUnmapWindow(VWindow(screen));
XMapWindow(screen->iconVwin.window);
return(TRUE);
}
} else {
i = (j = TFullWidth(screen) / 2) - (screen->Ttitle.x -
screen->title_n_size);
j = x - j;
if(j < 0)
j = -j;
if(j < i) {
XUnmapWindow(TWindow(screen));
XMapWindow(screen->iconTwin.window);
return(TRUE);
}
}
return(FALSE);
}

SyncUnmap(win, mask)
register Window win;
register int mask;
{
XEvent ev;
register XEvent *rep = &ev;

do { /* ignore events through unmap */
XWindowEvent(win, mask, rep);
} while(rep->type != UnmapWindow);
}

StartLog(screen)
register Screen *screen;
{
register char *cp;
register int i;
static char *log_default;
char *malloc(), *rindex();
extern logpipe();

if(screen->logging || (screen->inhibit & I_LOG))
return;
if(screen->logfile == NULL || *screen->logfile == 0) {
if(screen->logfile)
free(screen->logfile);
if(log_default == NULL)
mktemp(log_default = log_def_name);
if((screen->logfile = malloc(strlen(log_default) + 1)) == NULL)
return;
strcpy(screen->logfile, log_default);
}
if(*screen->logfile == '|') { /* exec command */
int p[2];
static char *shell;

if(pipe(p) < 0 || (i = fork()) < 0)
return;
if(i == 0) { /* child */
close(p[1]);
dup2(p[0], 0);
close(p[0]);
dup2(fileno(stderr), 1);
dup2(fileno(stderr), 2);
close(fileno(stderr));
fileno(stderr) = 2;
close(screen->display->fd);
close(screen->respond);
if(!shell) {
register struct passwd *pw;
char *getenv(), *malloc();
struct passwd *getpwuid();

if(((cp = getenv("SHELL")) == NULL || *cp == 0)
&& ((pw = getpwuid(screen->uid)) == NULL ||
*(cp = pw->pw_shell) == 0) ||
(shell = malloc(strlen(cp) + 1)) == NULL)
shell = "/bin/sh";
else
strcpy(shell, cp);
}
signal(SIGHUP, SIG_DFL);
signal(SIGCHLD, SIG_DFL);
setgid(screen->gid);
setuid(screen->uid);
execl(shell, shell, "-c", &screen->logfile[1], 0);
fprintf(stderr, "%s: Can't exec `%s'\n", xterm_name,
&screen->logfile[1]);
exit(ERROR_LOGEXEC);
}
close(p[0]);
screen->logfd = p[1];
signal(SIGPIPE, logpipe);
} else {
if(access(screen->logfile, F_OK) == 0) {
if(access(screen->logfile, W_OK) < 0)
return;
} else if(cp = rindex(screen->logfile, '/')) {
*cp = 0;
i = access(screen->logfile, W_OK);
*cp = '/';
if(i < 0)
return;
} else if(access(".", W_OK) < 0)
return;
if((screen->logfd = open(screen->logfile, O_WRONLY | O_APPEND |
O_CREAT, 0644)) < 0)
return;
chown(screen->logfile, screen->uid, screen->gid);

}
screen->logstart = screen->TekEmu ? Tbptr : bptr;
screen->logging = TRUE;
}

CloseLog(screen)
register Screen *screen;
{
if(!screen->logging || (screen->inhibit & I_LOG))
return;
FlushLog(screen);
close(screen->logfd);
screen->logging = FALSE;
}

FlushLog(screen)
register Screen *screen;
{
register char *cp;
register int i;

cp = screen->TekEmu ? Tbptr : bptr;
if((i = cp - screen->logstart) > 0)
write(screen->logfd, screen->logstart, i);
screen->logstart = screen->TekEmu ? Tbuffer : buffer;
}

logpipe()
{
register Screen *screen = &term.screen;

if(screen->logging)
CloseLog(screen);
}

do_osc(func)
int (*func)();
{
register Screen *screen = &term.screen;
register int mode, c;
register char *cp;
char buf[512];
extern char *malloc();

mode = 0;
while(isdigit(c = (*func)()))
mode = 10 * mode + (c - '0');
cp = buf;
while(isprint(c = (*func)()))
*cp++ = c;
*cp = 0;
switch(mode) {
case 0: /* new title */
Retitle(buf);
break;
case 46: /* new log file */
if((cp = malloc(strlen(buf) + 1)) == NULL)
break;
strcpy(cp, buf);
if(screen->logfile)
free(screen->logfile);
screen->logfile = cp;
break;
}
}

Retitle(name)
register char *name;
{
register Screen *screen = &term.screen;
register int w, i, j;
char icon[512];

free(screen->winname);
if((screen->winname = malloc((screen->winnamelen = strlen(name)) + 1))
== NULL)
Error(ERROR_RTMALLOC1);
strcpy(screen->winname, name);
strcpy(icon, name);
strcat(icon, " (icon)");
IconRecalc(screen);
if(screen->fullVwin.window) {
XStoreName(screen->fullVwin.window, name);
XStoreName(screen->iconVwin.window, icon);
XChangeWindow(screen->iconVwin.window, screen->iconVwin.width,
screen->iconVwin.height);
if(screen->title.tbar) {
w = FullWidth(screen);
screen->title.fullwidth = XQueryWidth(name,
screen->titlefont->id);
if((screen->title.width = i = screen->title.fullwidth)
> (j = w - 2 * (MINHILITE + screen->title_n_size + 1)))
screen->title.width = (i = j) +
screen->title_n_size;
j = w - i - 2 * (screen->title_n_size + 1);
i = j / 2;
j -= i;
screen->title.x = i + 1 + screen->title_n_size;
screen->title.y = TITLEPAD;
XClear(screen->title.tbar);
XChangeWindow(screen->title.left, i,
screen->titlefont->height);
XConfigureWindow(screen->title.right, w - j - 1,
TITLEPAD, j, screen->titlefont->height);
VTTitleExpose((XExposeWindowEvent *)NULL);
}
}
if(screen->fullTwin.window) {
free(screen->Twinname);
if((screen->Twinname = malloc((screen->Twinnamelen =
screen->winnamelen + 6) + 1)) == NULL)
Error(ERROR_RTMALLOC2);
strcpy(screen->Twinname, name);
strcat(screen->Twinname, " (Tek)");
XStoreName(screen->fullTwin.window, screen->Twinname);
XStoreName(screen->iconTwin.window, icon);
XChangeWindow(screen->iconTwin.window, screen->iconTwin.width,
screen->iconTwin.height);
if(screen->Ttitle.tbar) {
w = TFullWidth(screen);
screen->Ttitle.fullwidth = XQueryWidth(screen->Twinname,
screen->titlefont->id);
if((screen->Ttitle.width = i = screen->Ttitle.fullwidth)
> (j = w - 2 * (MINHILITE + screen->title_n_size + 1)))
screen->Ttitle.width = (i = j) +
screen->title_n_size;
j = w - i - 2 * (screen->title_n_size + 1);
i = j / 2;
j -= i;
screen->Ttitle.x = i + 1 + screen->title_n_size;
screen->Ttitle.y = TITLEPAD;
XClear(screen->Ttitle.tbar);
XChangeWindow(screen->Ttitle.left, i,
screen->titlefont->height);
XConfigureWindow(screen->Ttitle.right, w - j - 1,
TITLEPAD, j, screen->titlefont->height);
TekTitleExpose((XExposeWindowEvent *)NULL);
}
}
}

Panic(s, a)
char *s;
int a;
{
#ifdef DEBUG
if(debug) {
fprintf(stderr, "%s: PANIC! ", xterm_name);
fprintf(stderr, s, a);
fputs("\r\n", stderr);
fflush(stderr);
}
#endif DEBUG
}

SysError (i)
int i;
{
fprintf (stderr, "%s: Error %d, errno %d:", xterm_name, i, errno);
perror ("");
Cleanup(i);
}

Error (i)
int i;
{
fprintf (stderr, "%s: Error %d\n", xterm_name, i);
Cleanup(i);
}

/*
* cleanup by sending SIGHUP to client processes
*/
Cleanup (code)
int code;
{
#ifdef notdef
extern Terminal term;
register Screen *screen;

screen = &term.screen;
if (screen->pid > 1)
killpg(getpgrp(screen->pid), SIGHUP);
#endif
Exit (code);
}

/*
* sets the value of var to be arg in the Unix 4.2 BSD environment env.
* Var should end with '=' (bindings are of the form "var=value").
* This procedure assumes the memory for the first level of environ
* was allocated using calloc, with enough extra room at the end so not
* to have to do a realloc().
*/
Setenv (var, value)
register char *var, *value;
{
extern char **environ;
register int index = 0;
register int len = strlen(var);

while (environ [index] != NULL) {
if (strncmp (environ [index], var, len) == 0) {
/* found it */
environ[index] = (char *)malloc (len + strlen (value) + 1);
strcpy (environ [index], var);
strcat (environ [index], value);
return;
}
index ++;
}

#ifdef DEBUG
if (debug) fputs ("expanding env\n", stderr);
#endif DEBUG

environ [index] = (char *) malloc (len + strlen (value) + 1);
strcpy (environ [index], var);
strcat (environ [index], value);
environ [++index] = NULL;
}

/*
* returns a pointer to the first occurrence of s2 in s1,
* or NULL if there are none.
*/
char *strindex (s1, s2)
register char *s1, *s2;
{
register char *s3;
char *index();

while ((s3=index(s1, *s2)) != NULL) {
if (strncmp(s3, s2, strlen(s2)) == 0)
return (s3);
s1 = ++s3;
}
return (NULL);
}

xerror(d, ev)
Display *d;
register XErrorEvent *ev;
{
fprintf(stderr, "%s: %s\n", xterm_name,
XErrDescrip(ev->error_code));
fprintf(stderr, "Request code %d, func %d, serial #%ld, window %ld\n",
ev->request_code, ev->func, ev->serial, (long)ev->window);
Exit(ERROR_XERROR);
}

xioerror(d)
Display *d;
{
perror(xterm_name);
Exit(ERROR_XIOERROR);
}
RAZZLE!DAZZLE
fi # End misc.c
if test -f resize.c
then
echo shar: will not overwrite existing file "'resize.c'"
else
echo 'x - resize.c'
cat << \RAZZLE!DAZZLE > resize.c
/*
* $Source: /u1/X/xterm/RCS/resize.c,v $
* $Header: resize.c,v 10.101 86/12/02 10:35:30 swick Exp $
*/

#ifndef lint
static char *rcsid_resize_c = "$Header: resize.c,v 10.101 86/12/02 10:35:30 swick Exp $";
#endif lint

#include <X/mit-copyright.h>

/* Copyright Massachusetts Institute of Technology 1984 */

/* resize.c */

#include <stdio.h>
#include <sgtty.h>
#include <strings.h>
#include <ctype.h>
#include <sys/ioctl.h>
#include <signal.h>
#include <sys/time.h>

#ifndef lint
static char sccs_id[] = "@(#)resize.c\tX10/6.6B\t12/26/86";
#endif

#define EMULATIONS 2
#define SUN 1
#define TIMEOUT 10
#define VT100 0

char *emuname[EMULATIONS] = {
"VT100",
"Sun",
};
char *myname;
int stdsh;
char *getsize[EMULATIONS] = {
"\0337\033[r\033[999;999H\033[6n",
"\033[18t",
};
#ifndef sun
#ifdef TIOCSWINSZ
char *getwsize[EMULATIONS] = {
0,
"\033[14t",
};
#endif TIOCSWINSZ
#endif sun
char *restore[EMULATIONS] = {
"\0338",
0,
};
char *setname = "";
char *setsize[EMULATIONS] = {
0,
"\033[8;%s;%st",
};
struct sgttyb sgorig;
char *size[EMULATIONS] = {
"\033[%d;%dR",
"\033[8;%d;%dt",
};
char sunname[] = "sunsize";
int tty;
FILE *ttyfp;
#ifndef sun
#ifdef TIOCSWINSZ
char *wsize[EMULATIONS] = {
0,
"\033[4;%hd;%hdt",
};
#endif TIOCSWINSZ
#endif sun

char *strindex (), *index (), *rindex();

main (argc, argv)
char **argv;
/*
resets termcap string to reflect current screen size
*/
{
register char *ptr, *env;
register int emu = VT100;
int rows, cols;
struct sgttyb sg;
char termcap [1024];
char newtc [1024];
char buf[BUFSIZ];
#ifdef sun
#ifdef TIOCSSIZE
struct ttysize ts;
#endif TIOCSSIZE
#else sun
#ifdef TIOCSWINSZ
struct winsize ws;
#endif TIOCSWINSZ
#endif sun
char *getenv();
int onintr();

if(ptr = rindex(myname = argv[0], '/'))
myname = ptr + 1;
if(strcmp(myname, sunname) == 0)
emu = SUN;
for(argv++, argc-- ; argc > 0 && **argv == '-' ; argv++, argc--) {
switch((*argv)[1]) {
case 's': /* Sun emulation */
if(emu == SUN)
Usage(); /* Never returns */
emu = SUN;
break;
case 'u': /* Bourne (Unix) shell */
stdsh++;
break;
default:
Usage(); /* Never returns */
}
}
if(argc == 2) {
if(!setsize[emu]) {
fprintf(stderr,
"%s: Can't set window size under %s emulation\n",
myname, emuname[emu]);
exit(1);
}
if(!checkdigits(argv[0]) || !checkdigits(argv[1]))
Usage(); /* Never returns */
} else if(argc != 0)
Usage(); /* Never returns */
if((ttyfp = fopen("/dev/tty", "r+")) == NULL) {
fprintf(stderr, "%s: Can't open /dev/tty\n", myname);
exit(1);
}
tty = fileno(ttyfp);
if((env = getenv("TERMCAP")) && *env)
strcpy(termcap, env);
else {
if(!(env = getenv("TERM")) || !*env) {
env = "xterm";
if(stdsh)
setname = "TERM=xterm;\n";
else setname = "setenv TERM xterm;\n";
}
if(tgetent (termcap, env) <= 0) {
fprintf(stderr, "%s: Can't get entry \"%s\"\n",
myname, env);
exit(1);
}
}

ioctl (tty, TIOCGETP, &sgorig);
sg = sgorig;
sg.sg_flags |= RAW;
sg.sg_flags &= ~ECHO;
signal(SIGINT, onintr);
signal(SIGQUIT, onintr);
signal(SIGTERM, onintr);
ioctl (tty, TIOCSETP, &sg);

if (argc == 2) {
sprintf (buf, setsize[emu], argv[0], argv[1]);
write(tty, buf, strlen(buf));
}
write(tty, getsize[emu], strlen(getsize[emu]));
readstring(ttyfp, buf, size[emu]);
if(sscanf (buf, size[emu], &rows, &cols) != 2) {
fprintf(stderr, "%s: Can't get rows and columns\r\n", myname);
onintr();
}
if(restore[emu])
write(tty, restore[emu], strlen(restore[emu]));
#ifdef sun
#ifdef TIOCGSIZE
/* finally, set the tty's window size */
if (ioctl (tty, TIOCGSIZE, &ts) != -1) {
ts.ts_lines = rows;
ts.ts_cols = cols;
ioctl (tty, TIOCSSIZE, &ts);
}
#endif TIOCGSIZE
#else sun
#ifdef TIOCGWINSZ
/* finally, set the tty's window size */
if(getwsize[emu]) {
/* get the window size in pixels */
write (tty, getwsize[emu], strlen (getwsize[emu]));
readstring(ttyfp, buf, wsize[emu]);
if(sscanf (buf, wsize[emu], &ws.ws_xpixel, &ws.ws_ypixel) != 2) {
fprintf(stderr, "%s: Can't get window size\r\n", myname);
onintr();
}
ws.ws_row = rows;
ws.ws_col = cols;
ioctl (tty, TIOCSWINSZ, &ws);
} else if (ioctl (tty, TIOCGWINSZ, &ws) != -1) {
/* we don't have any way of directly finding out
the current height & width of the window in pixels. We try
our best by computing the font height and width from the "old"
struct winsize values, and multiplying by these ratios...*/
if (ws.ws_xpixel != 0)
ws.ws_xpixel = cols * (ws.ws_xpixel / ws.ws_col);
if (ws.ws_ypixel != 0)
ws.ws_ypixel = rows * (ws.ws_ypixel / ws.ws_row);
ws.ws_row = rows;
ws.ws_col = cols;
ioctl (tty, TIOCSWINSZ, &ws);
}
#endif TIOCGWINSZ
#endif sun

ioctl (tty, TIOCSETP, &sgorig);
signal(SIGINT, SIG_DFL);
signal(SIGQUIT, SIG_DFL);
signal(SIGTERM, SIG_DFL);

/* update termcap string */
/* first do columns */
if ((ptr = strindex (termcap, "co#")) == NULL) {
fprintf(stderr, "%s: No `co#'\n", myname);
exit (1);
}
strncpy (newtc, termcap, ptr - termcap + 3);
sprintf (newtc + strlen (newtc), "%d", cols);
ptr = index (ptr, ':');
strcat (newtc, ptr);

/* now do lines */
if ((ptr = strindex (newtc, "li#")) == NULL) {
fprintf(stderr, "%s: No `li#'\n", myname);
exit (1);
}
strncpy (termcap, newtc, ptr - newtc + 3);
sprintf (termcap + ((int) ptr - (int) newtc + 3), "%d", rows);
ptr = index (ptr, ':');
strcat (termcap, ptr);

if(stdsh)
printf ("%sTERMCAP='%s'\n",
setname, termcap);
else printf ("set noglob;\n%ssetenv TERMCAP '%s';\nunset noglob;\n",
setname, termcap);
exit(0);
}

char *strindex (s1, s2)
/*
returns a pointer to the first occurrence of s2 in s1, or NULL if there are
none.
*/
register char *s1, *s2;
{
register char *s3;

while ((s3 = index (s1, *s2)) != NULL)
{
if (strncmp (s3, s2, strlen (s2)) == 0) return (s3);
s1 = ++s3;
}
return (NULL);
}

checkdigits(str)
register char *str;
{
while(*str) {
if(!isdigit(*str))
return(0);
str++;
}
return(1);
}

readstring(fp, buf, str)
register FILE *fp;
register char *buf;
char *str;
{
register int i, last;
struct itimerval it;
int timeout();

signal(SIGALRM, timeout);
bzero((char *)&it, sizeof(struct itimerval));
it.it_value.tv_sec = TIMEOUT;
setitimer(ITIMER_REAL, &it, (struct itimerval *)NULL);
if((*buf++ = getc(fp)) != *str) {
fprintf(stderr, "%s: unknown character, exiting.\r\n", myname);
onintr();
}
last = str[i = strlen(str) - 1];
while((*buf++ = getc(fp)) != last);
bzero((char *)&it, sizeof(struct itimerval));
setitimer(ITIMER_REAL, &it, (struct itimerval *)NULL);
*buf = 0;
}

Usage()
{
fprintf(stderr, strcmp(myname, sunname) == 0 ?
"Usage: %s [rows cols]\n" :
"Usage: %s [-u] [-s [rows cols]]\n", myname);
exit(1);
}

timeout()
{
fprintf(stderr, "%s: Time out occurred\r\n", myname);
onintr();
}

onintr()
{
ioctl (tty, TIOCSETP, &sgorig);
exit(1);
}
RAZZLE!DAZZLE
fi # End resize.c
if test -f screen.c
then
echo shar: will not overwrite existing file "'screen.c'"
else
echo 'x - screen.c'
cat << \RAZZLE!DAZZLE > screen.c
/*
* $Source: /u1/X/xterm/RCS/screen.c,v $
* $Header: screen.c,v 10.100 86/12/01 14:45:17 jg Rel $
*/

#include <X/mit-copyright.h>

/* Copyright Massachusetts Institute of Technology 1984, 1985 */

/* screen.c */

#ifndef lint
static char sccs_id[] = "@(#)screen.c\tX10/6.6B\t12/26/86";
#endif lint

#include <X/Xlib.h>
#include <stdio.h>
#include <sys/ioctl.h>
#include <signal.h>
#include "scrollbar.h"
#include "ptyx.h"
#include "error.h"

extern char *calloc();
extern char *malloc();
extern char *realloc();

ScrnBuf Allocate (nrow, ncol)
/*
allocates memory for a 2-dimensional array of chars and returns a pointer
thereto
each line is formed from a pair of char arrays. The first (even) one is
the actual character array and the second (odd) one is the attributes.
*/
register int nrow, ncol;
{
register ScrnBuf base;

if ((base = (ScrnBuf) calloc ((nrow *= 2), sizeof (char *))) == 0)
SysError (ERROR_SCALLOC);

for (nrow--; nrow >= 0; nrow--)
if ((base [nrow] = calloc (ncol, sizeof(char))) == 0)
SysError (ERROR_SCALLOC2);

return (base);
}

ScreenWrite (screen, str, flags, length)
/*
Writes str into buf at row row and column col. Characters are set to match
flags.
*/
Screen *screen;
char *str;
register unsigned flags;
register int length; /* length of string */
{
register char *att;
register int avail = screen->max_col - screen->cur_col + 1;
register char *col;

if (length > avail)
length = avail;
if (length <= 0)
return;

col = screen->buf[avail = 2 * screen->cur_row] + screen->cur_col;
att = screen->buf[avail + 1] + screen->cur_col;
flags &= ATTRIBUTES;
bcopy(str, col, length);
while(length-- > 0)
*att++ = flags;
}

ScrnInsertLine (sb, last, where, n, size)
/*
Inserts n blank lines at sb + where, treating last as a bottom margin.
Size is the size of each entry in sb.
Requires: 0 <= where < where + n <= last
n <= MAX_ROWS
*/
register ScrnBuf sb;
int last;
register int where, n, size;
{
register int i;
char *save [2 * MAX_ROWS];

/* save n lines at bottom */
bcopy ((char *) &sb [2 * (last -= n - 1)], (char *) save,
2 * sizeof (char *) * n);

/* clear contents of old rows */
for (i = 2 * n - 1; i >= 0; i--)
bzero ((char *) save [i], size);

/* move down lines */
bcopy ((char *) &sb [2 * where], (char *) &sb [2 * (where + n)],
2 * sizeof (char *) * (last - where));

/* reuse storage for new lines at where */
bcopy ((char *)save, (char *) &sb[2 * where], 2 * sizeof(char *) * n);
}


ScrnDeleteLine (sb, last, where, n, size)
/*
Deletes n lines at sb + where, treating last as a bottom margin.
Size is the size of each entry in sb.
Requires 0 <= where < where + n < = last
n <= MAX_ROWS
*/
register ScrnBuf sb;
register int n, last, size;
int where;
{
register int i;
char *save [2 * MAX_ROWS];

/* save n lines at where */
bcopy ((char *) &sb[2 * where], (char *)save, 2 * sizeof(char *) * n);

/* clear contents of old rows */
for (i = 2 * n - 1 ; i >= 0 ; i--)
bzero ((char *) save [i], size);

/* move up lines */
bcopy ((char *) &sb[2 * (where + n)], (char *) &sb[2 * where],
2 * sizeof (char *) * ((last -= n - 1) - where));

/* reuse storage for new bottom lines */
bcopy ((char *)save, (char *) &sb[2 * last],
2 * sizeof(char *) * n);
}


ScrnInsertChar (sb, row, col, n, size)
/*
Inserts n blanks in sb at row, col. Size is the size of each row.
*/
ScrnBuf sb;
int row, size;
register int col, n;
{
register int i, j;
register char *ptr = sb [2 * row];
register char *att = sb [2 * row + 1];

for (i = size - 1; i >= col + n; i--) {
ptr[i] = ptr[j = i - n];
att[i] = att[j];
}

bzero (ptr + col, n);
bzero (att + col, n);
}


ScrnDeleteChar (sb, row, col, n, size)
/*
Deletes n characters in sb at row, col. Size is the size of each row.
*/
ScrnBuf sb;
register int row, size;
register int n, col;
{
register char *ptr = sb[2 * row];
register char *att = sb[2 * row + 1];
register nbytes = (size - n - col);

bcopy (ptr + col + n, ptr + col, nbytes);
bcopy (att + col + n, att + col, nbytes);
bzero (ptr + size - n, n);
bzero (att + size - n, n);
}


ScrnRefresh (screen, toprow, leftcol, nrows, ncols)
/*
Repaints the area enclosed by the parameters.
Requires: (toprow, leftcol), (toprow + nrows, leftcol + ncols) are
coordinates of characters in screen;
nrows and ncols positive.
*/
register Screen *screen;
int toprow, leftcol, nrows, ncols;
{
int y = toprow * FontHeight(screen) + screen->border + Titlebar(screen);
register int row;
register int topline = screen->topline;
int maxrow = toprow + nrows - 1;
int scrollamt = screen->scroll_amt;
int max = screen->max_row;
int dostatus = 0, left, width;

if(screen->statusline && maxrow == screen->max_row + 1) {
dostatus++;
maxrow--;
}
if(screen->cursor_col >= leftcol && screen->cursor_col <=
(leftcol + ncols - 1) && screen->cursor_row >= toprow + topline &&
screen->cursor_row <= maxrow + topline)
screen->cursor_state = OFF;
for( ; ; ) {
for (row = toprow; row <= maxrow; y += FontHeight(screen), row++)
{
register char *chars;
register char *att;
register int col = leftcol;
int maxcol = leftcol + ncols - 1;
int lastind;
int flags;
int gxfunction;
Font fnt;
int x, yb, pix, n;

lastind = row - scrollamt;
if (lastind < 0 || lastind > max)
continue;
chars = screen->buf [2 * (lastind + topline)];
att = screen->buf [2 * (lastind + topline) + 1];

while (col <= maxcol && (att[col] & ~BOLD) == 0 &&
(chars[col] & ~040) == 0)
col++;

while (col <= maxcol && (att[maxcol] & ~BOLD) == 0 &&
(chars[maxcol] & ~040) == 0)
maxcol--;

if (col > maxcol) continue;

flags = att[col];

fnt = ActiveIcon(screen)
? screen->fnt_icon
: (flags & BOLD)
? screen->fnt_bold
: screen->fnt_norm;

x = col * FontWidth(screen) + screen->border;
lastind = col;

for (; col <= maxcol; col++) {
if (att[col] != flags) {
if (((flags & INVERSE) != 0) ^ (dostatus < 0 &&
screen->reversestatus))
XText (VWindow(screen), x, y, &chars[lastind],
n = col - lastind, fnt,
pix = screen->background, screen->foreground);
else
XText (VWindow(screen), x, y, &chars[lastind],
n = col - lastind, fnt,
pix = screen->foreground, screen->background);
if((flags & BOLD) && screen->enbolden)
XTextMask (VWindow(screen), x + 1, y, &chars[lastind],
n, fnt, pix);
if(flags & UNDERLINE) {
yb = y + FontHeight(screen) - 2;
XLine(VWindow(screen), x, yb, x + n * FontWidth(screen),
yb, 1, 1, pix, GXcopy, AllPlanes);
}

x += (col - lastind) * FontWidth(screen);

lastind = col;

flags = att[col];

fnt = ActiveIcon(screen)
? screen->fnt_icon
: (flags & BOLD)
? screen->fnt_bold
: screen->fnt_norm;
}

if(chars[col] == 0)
chars[col] = ' ';
}

if (((flags & INVERSE) != 0) ^ (dostatus < 0 &&
screen->reversestatus))
XText (VWindow(screen), x, y, &chars[lastind],
n = col - lastind, fnt, pix = screen->background,
screen->foreground);
else
XText (VWindow(screen), x, y, &chars[lastind],
n = col - lastind, fnt, pix = screen->foreground,
screen->background);
if((flags & BOLD) && screen->enbolden)
XTextMask (VWindow(screen), x + 1, y, &chars[lastind],
n, fnt, pix);
if(flags & UNDERLINE) {
yb = y + FontHeight(screen) - 2;
XLine(VWindow(screen), x, yb, x + n * FontWidth(screen), yb, 1, 1,
pix, GXcopy, AllPlanes);
}
}
if(dostatus <= 0)
break;
dostatus = -1;
topline = 0;
scrollamt = 0;
toprow = maxrow = max = screen->max_row + 1;
left = leftcol * FontWidth(screen) + screen->border;
width = ncols * FontWidth(screen);
if(leftcol == 0) {
left--;
width++;
}
if(leftcol + ncols - 1 >= screen->max_col)
width++;
XPixSet(VWindow(screen), left, y, width, screen->statusheight,
screen->reversestatus ? screen->foreground : screen->background);
if(!screen->reversestatus)
StatusBox(screen);
y++;
}
}

ClearBufRows (screen, first, last)
/*
Sets the rows first though last of the buffer of screen to spaces.
Requires first <= last; first, last are rows of screen->buf.
*/
register Screen *screen;
register int first, last;
{
first *= 2;
last = 2 * last + 1;
while (first <= last)
bzero (screen->buf [first++], (screen->max_col + 1));
}

ScreenResize (screen, width, height, flags)
/*
Resizes screen:
1. If new window would have fractional characters, sets window size so as to
discard fractional characters and returns -1.
Minimum screen size is 1 X 1.
Note that this causes another ExposeWindow event.
2. Enlarges screen->buf if necessary. New space is appended to the bottom
and to the right
3. Reduces screen->buf if necessary. Old space is removed from the bottom
and from the right
4. Cursor is positioned as closely to its former position as possible
5. Sets screen->max_row and screen->max_col to reflect new size
6. Maintains the inner border.
7. Clears origin mode and sets scrolling region to be entire screen.
8. Returns 0
*/
register Screen *screen;
int width, height;
unsigned *flags;
{
register int rows, cols;
register int index;
register int savelines;
register ScrnBuf sb = screen->allbuf;
register ScrnBuf ab = screen->altbuf;
register int x;
register int border = 2 * screen->border;
register int extra, i, j, k;
register char *sl0, *sl1; /* keep status line */
double scale_x, scale_y;
#ifdef sun
#ifdef TIOCSSIZE
struct ttysize ts;
#endif TIOCSSIZE
#else sun
#ifdef TIOCSWINSZ
struct winsize ws;
#endif TIOCSWINSZ
#endif sun


if (ActiveIcon(screen)) return( 0 ); /* don't resize on icon exposure */

extra = Titlebar(screen) + screen->statusheight;
/* round so that it is unlikely the screen will change size on */
/* small mouse movements. */
rows = (height + FontHeight(screen) / 2 - border - extra) /
FontHeight(screen);
cols = (width + FontWidth(screen) / 2 - border - screen->scrollbar) /
FontWidth(screen);
if (rows < 1) rows = 1;
if (cols < 1) cols = 1;

if ((width - border - screen->scrollbar) % FontWidth(screen)
!= 0 || (height - border - extra) % FontHeight(screen) != 0 ||
rows < screen->minrows) {
XChangeWindow (VWindow(screen),
cols * FontWidth(screen) + border + screen->scrollbar,
(rows < screen->minrows ? screen->minrows : rows) *
FontHeight(screen) + border + extra);
return (-1);
}

/* change buffers if the screen has changed size */
if (screen->max_row != rows - 1 || screen->max_col != cols - 1) {
if(screen->cursor_state)
HideCursor();
savelines = screen->sb ? screen->savelines : 0;
j = screen->max_col + 1;
i = cols - j;
k = screen->max_row;
if(rows < k)
k = rows;
if(ab) {
/* resize current lines in alternate buf */
for (index = x = 0; index <= k; x += 2, index++) {
if ((ab[x] = realloc(ab[x], cols)) == NULL)
SysError(ERROR_SREALLOC);
if((ab[x + 1] = realloc(ab[x + 1], cols)) ==
NULL)
SysError (ERROR_SREALLOC2);
if (cols > j) {
bzero (ab [x] + j, i);
bzero (ab [x + 1] + j, i);
}
}
/* discard excess bottom rows in alt buf */
for (index = rows, x = 2 * k ; index <=
screen->max_row; x += 2, index++) {
free (ab [x]);
free (ab [x + 1]);
}
}
/* resize current lines */
k += savelines + 1; /* includes status line */
for (index = x = 0; index <= k; x += 2, index++) {
if ((sb[x] = realloc(sb[x], cols)) == NULL)
SysError(ERROR_SREALLOC3);
if((sb[x + 1] = realloc(sb[x + 1], cols)) == NULL)
SysError (ERROR_SREALLOC4);
if (cols > j) {
bzero (sb [x] + j, i);
bzero (sb [x + 1] + j, i);
}
}
/* discard excess bottom rows, but not status line */
for (index = rows, x = 2 * (k - 1); index <= screen->max_row;
x += 2, index++) {
free (sb [x]);
free (sb [x + 1]);
}
if(ab) {
if((ab = (ScrnBuf)realloc(ab, 2 * sizeof(char *) * rows))
== NULL)
SysError (ERROR_RESIZE);
screen->altbuf = ab;
}
/* save status line */
sl0 = sb[i = 2 * (savelines + screen->max_row + 1)];
sl1 = sb[i + 1];
k = 2 * (rows + savelines + 1); /* includes status line */
/* resize sb */
if((sb = (ScrnBuf)realloc(sb, k * sizeof(char *))) == NULL)
SysError (ERROR_RESIZE2);
screen->allbuf = sb;
screen->buf = &sb[2 * savelines];

if(ab) {
/* create additional bottom rows as required in alt */
for (index = screen->max_row + 1, x = 2 * index ;
index < rows; x += 2, index++) {
if((ab[x] = calloc (cols, sizeof(char))) == NULL)
SysError(ERROR_RESIZROW);
if((ab[x + 1] = calloc (cols, sizeof(char))) == NULL)
SysError(ERROR_RESIZROW2);
}
}
/* create additional bottom rows as required */
for (index = screen->max_row + 1, x = 2 * (index + savelines) ;
index < rows; x += 2, index++) {
if((sb[x] = calloc (cols, sizeof(char))) == NULL)
SysError(ERROR_RESIZROW3);
if((sb[x + 1] = calloc (cols, sizeof(char))) == NULL)
SysError(ERROR_RESIZROW4);
}

/* reinstall status line */
sb[x = 2 * (rows + savelines)] = sl0;
sb[x + 1] = sl1;

screen->max_row = rows - 1;
screen->max_col = cols - 1;

/* adjust scrolling region */
screen->top_marg = 0;
screen->bot_marg = screen->max_row;
*flags &= ~ORIGIN;

if (screen->instatus)
screen->cur_row = screen->max_row + 1;
else if (screen->cur_row > screen->max_row)
screen->cur_row = screen->max_row;
if (screen->cur_col > screen->max_col)
screen->cur_col = screen->max_col;

screen->fullVwin.height = height - border - extra;
screen->fullVwin.width = width - border - screen->scrollbar;

if (screen->active_icon)
SetIconSize( screen );

} else if(FullHeight(screen) == height && FullWidth(screen) == width)
return(0); /* nothing has changed at all */

if(screen->sb)
ResizeScrollBar(screen->sb, width - SCROLLBARWIDTH,
Titlebar(screen) - 1, height - Titlebar(screen), rows);
if(screen->title.tbar && FullWidth(screen) != width)
VTTitleResize(width);

screen->fullVwin.fullheight = height;
screen->fullVwin.fullwidth = width;
#ifdef sun
#ifdef TIOCSSIZE
/* Set tty's idea of window size */
ts.ts_lines = rows;
ts.ts_cols = cols;
ioctl (screen->respond, TIOCSSIZE, &ts);
#ifdef SIGWINCH
if(screen->pid > 1)
killpg(getpgrp(screen->pid), SIGWINCH);
#endif SIGWINCH
#endif TIOCSSIZE
#else sun
#ifdef TIOCSWINSZ
/* Set tty's idea of window size */
ws.ws_row = rows;
ws.ws_col = cols;
ws.ws_xpixel = width;
ws.ws_ypixel = height;
ioctl (screen->respond, TIOCSWINSZ, &ws);
#ifdef SIGWINCH
if(screen->pid > 1)
killpg(getpgrp(screen->pid), SIGWINCH);
#endif SIGWINCH
#endif TIOCSWINSZ
#endif sun
return (0);
}


SetIconSize( screen )
Screen *screen;
{
if (screen->active_icon) {
screen->iconVwin.width = (screen->max_col + 1)
* screen->iconVwin.f_width
+ screen->border * 2;
screen->iconVwin.height = (screen->max_row + 1)
* screen->iconVwin.f_height
+ screen->border * 2;
XChangeWindow( screen->iconVwin.window,
screen->iconVwin.width,
screen->iconVwin.height );
} else {
IconRecalc( screen );
}

screen->iconVwin.fullwidth = screen->iconVwin.width;
screen->iconVwin.fullheight = screen->iconVwin.height;
}
RAZZLE!DAZZLE
fi # End screen.c
echo '***** End of' xterm 6.6B - Part 6 of 7 '*****'
exit

0 new messages