|
|
DataMuseum.dkPresents historical artifacts from the history of: DKUUG/EUUG Conference tapes |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about DKUUG/EUUG Conference tapes Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - metrics - downloadIndex: T m
Length: 32475 (0x7edb)
Types: TextFile
Names: »misc.c«
└─⟦a0efdde77⟧ Bits:30001252 EUUGD11 Tape, 1987 Spring Conference Helsinki
└─⟦526ad3590⟧ »EUUGD11/gnu-31mar87/X.V10.R4.tar.Z«
└─⟦2109abc41⟧
└─⟦this⟧ »./X.V10R4/xterm/misc.c«
/*
* $Source: /u1/X/xterm/RCS/misc.c,v $
* $Header: misc.c,v 10.106 86/12/24 08:29:28 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.6\t11/11/86";
#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:
#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();
screen->select = 0;
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);
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);
}