Category : Files from Magazines
Archive   : DDJ0988.ZIP
Filename : STEVENS.LIS

 
Output of file : STEVENS.LIS contained in archive : DDJ0988.ZIP

_C PROGRAMMING_
by
Al Stevens

Listing One

/* ---------- window.h ----------- */

void establish_window(int,int,int,int,int,int,int);
void window_title(char *);
void clear_window(void);
void delete_window(void);
void scroll_window(int);
void text_window(char **, int);
int select_window(int, int, int, int (*func)(int,int));
int getkey(void);
void hidecursor(void);
void set_cursor_type(unsigned);
void clear_screen(void);
void writeline(int, int, char *);
void current_window(void);
void error_message(char *);

#define MAX_WINDOWS 10 /* maximum windows open at once */

#define TRUE 1
#define FALSE 0
#define ERROR -1

#define BELL 7
#define ESC 27
#define SHIFT_HT 143
#define CTRL_T 20
#define CTRL_B 2
#define CTRL_D 4
#define ALT_D 160
#define ALT_F 161
#define ALT_E 146
#define ALT_O 152
#define ALT_S 159

#define F1 187
#define F2 188
#define F3 189
#define F4 190
#define F5 191
#define F6 192
#define F7 193
#define F8 194
#define F9 195
#define F10 196
#define ALT_F7 238

#define HOME 199
#define UP 200
#define PGUP 201
#define BS 203
#define FWD 205
#define END 207
#define DN 208
#define PGDN 209
#define INS 210
#define DEL 211

#define CTRL_HOME 247
#define CTRL_BS 243
#define CTRL_FWD 244
#define CTRL_END 245

/* --------- window definition structure ------------ */
struct wn {
int lf,tp,rt,bt; /* window position */
int ht,wd; /* window dimensions */
int wx, wy; /* window cursor */
int wtop; /* top text line */
int wlines; /* total text lines */
int fg,bg; /* window colors */
char *wsave; /* video memory save buffer */
char **wtext; /* pointer to text */
};

/* ------ internal Turbo C stuff ------- */
void far * pascal __vptr(int, int);
void pascal __vram(void far *, void far *, int);
extern struct {
char filler1[4];
char attribute;
char filler2[5];
char snow;
} _video;

/* ------------ window colors --------------- */
#define TEXTFG WHITE /* data display screen */
#define TEXTBG BLACK
#define BLOCKFG BLACK /* data blocks */
#define BLOCKBG WHITE
#define HELPBG WHITE /* help windows */
#define HELPFG BLACK
#define MENUBG WHITE /* menus */
#define MENUFG BLACK
#define SELECTBG BLACK /* menu selector bars */
#define SELECTFG WHITE
#define ENTRYFG WHITE /* data entry windows */
#define ENTRYBG BLACK
#define FIELDFG BLACK /* data entry fields */
#define FIELDBG WHITE
#define ERRORFG BLACK /* error messages */
#define ERRORBG WHITE



Listing Two

/* ----------------------- window.c --------------------- */

#include
#include
#include
#include
#include
#include
#include
#include "window.h"

/* --------- window border characters ---------------- */
#define NW '\332'
#define NE '\277'
#define SE '\331'
#define SW '\300'
#define SIDE '\263'
#define LINE '\304'

int editing;
static union REGS rg;

/* --------- window definition structure ------------ */
struct wn wdo [MAX_WINDOWS];
int curr_wnd; /* current window */
struct wn wkw; /* a working window structure */

static void upline(void);
static void downline(void);
static void firstline(void);
static void lastline(void);
static void dline(int, int, int);

/* ----------- establish a new window -------------- */
void establish_window(left,top,right,bottom,foreg,backg,save)
{
if (curr_wnd < MAX_WINDOWS) {
if (curr_wnd)
wdo[curr_wnd-1] = wkw;
setmem(&wkw, sizeof(wkw), 0);
wkw.lf = left;
wkw.tp = top;
wkw.rt = right;
wkw.bt = bottom;
wkw.fg = foreg;
wkw.bg = backg;
wkw.wd = right+1-left;
wkw.ht = bottom-top-1;
if (save) {
if ((wkw.wsave=malloc((wkw.ht+2)*wkw.wd*2)) == NULL)
return;
gettext(left, top, right, bottom, wkw.wsave);
}
wdo[curr_wnd++] = wkw;
current_window();
clear_window();
}
}

/* ------- initialize the working window as current -------- */
void current_window()
{
window(wkw.lf,wkw.tp,wkw.rt,wkw.bt);
hidecursor();
if (wkw.fg || wkw.bg) {
textcolor(wkw.fg);
textbackground(wkw.bg);
}
}

/* ----------- set a window's title -------------- */
void window_title(char *ttl)
{
writeline((wkw.wd-strlen(ttl)) / 2, 1, ttl);
}

/* ------------ remove a window ------------------ */
void delete_window()
{
if (curr_wnd) {
if (wkw.wsave) {
puttext(wkw.lf,wkw.tp,wkw.rt,wkw.bt,wkw.wsave);
free(wkw.wsave);
}
setmem(wdo+curr_wnd-1, sizeof (struct wn), 0);
--curr_wnd;
if (curr_wnd) {
wkw = wdo[curr_wnd-1];
current_window();
}
}
}

/* ---- clear the window area and display the border ----- */
void clear_window()
{
int height, width, y = 1;
char line1[81], line2[81];

height = wkw.ht;
width = wkw.wd;
setmem(line1 + 1, width-1, LINE);
setmem(line2 + 1, width-1, ' ');
*line1 = NW;
line1[width-1] = NE;
line1[width] = '\0';
*line2 = SIDE;
line2[width-1] = SIDE;
line2[width] = '\0';
line1[width] = line2[width] = '\0';
writeline(1, y++, line1);
while (height--)
writeline(1, y++, line2);
*line1 = SW;
line1[width-1] = SE;
writeline(1, y, line1);
}

/* --------- scroll the window. d: 1 = up, 0 = dn ---------- */
void scroll_window(d)
{
if (_video.snow == 0)
movetext(wkw.lf+1, wkw.tp+1+d,
wkw.rt-1, wkw.bt-2+d,
wkw.lf+1, wkw.tp+2-d);
else {
rg.h.ah = d ? 6 : 7;
rg.h.al = 1;
rg.h.bh = _video.attribute;
rg.h.cl = wkw.lf;
rg.h.ch = wkw.tp;
rg.h.dl = wkw.rt-2;
rg.h.dh = wkw.bt-2;
int86(16, &rg, &rg);
}
}

/* ---------- display text in a window --------------- */
void text_window(char *txt[], int ln)
{
int height = wkw.ht;

wkw.wtext = txt;
wkw.wtop = ln;
wkw.wy = 1;
while (height-- && txt[ln-1])
dline(ln++, wkw.fg, wkw.bg);
wkw.wlines = 0;
while (*txt++)
wkw.wlines++;
}

static int lineno;
/* -------- page and scroll through a window of text -------- */
int
select_window(int ln,int foreg,int backg,int (*func)(int,int))
{
int c = 0;
int frtn;
int height, dln, ptop;

if (ln > wkw.wtop + wkw.ht-1 || ln < wkw.wtop)
text_window(wkw.wtext, ln);
else
wkw.wy = ln - wkw.wtop + 1;
while (TRUE) {
lineno = wkw.wtop + wkw.wy - 1;
ptop = wkw.wtop;
dline(lineno, foreg, backg);
if (wkw.wx == 0)
hidecursor();
else
gotoxy(wkw.wx, wkw.wy+1);
c = getkey();
if (c == '\r' || c == ESC)
break;
switch (c) {
case CTRL_HOME:
firstline();
break;
case CTRL_END:
lastline();
break;
case PGUP:
wkw.wtop -= wkw.ht;
if (wkw.wtop < 1)
wkw.wtop = 1;
break;
case PGDN:
wkw.wtop += wkw.ht;
if (wkw.wtop > wkw.wlines - (wkw.ht-1)) {
wkw.wtop = wkw.wlines - (wkw.ht-1);
if (wkw.wtop < 1)
wkw.wtop = 1;
}
break;
case UP:
upline();
break;
case DN:
downline();
break;
default:
if (!editing && wkw.wlines <= wkw.ht) {
if (c == HOME) {
firstline();
break;
}
if (c == END) {
lastline();
break;
}
}
if (func) {
frtn = (*func)(c, lineno);

if (frtn == ERROR)
putch(BELL);
else if (frtn) {
wkw.wy = frtn;
return frtn;
}
c = 0;
}
break;
}
switch (c) {
case HOME:
case CTRL_HOME:
case END:
case CTRL_END:
case PGUP:
case PGDN: if (wkw.wtop != ptop) {
height = wkw.ht;
dln = wkw.wtop;
while (height-- && wkw.wtext[dln-1])
dline(dln++, wkw.fg, wkw.bg);
break;
}
default: dline(lineno, wkw.fg, wkw.bg);
break;
}
}
return c == ESC ? 0 : lineno;
}

/* ---------- move up one line --------------- */
static void upline()
{
if (lineno > 1) {
if (wkw.wy == 1) {
if (wkw.wtop > 1) {
--wkw.wtop;
scroll_window(0);
}
}
else
--wkw.wy;
}
else if (wkw.wlines <= wkw.ht)
lastline();
}

/* ----------- move down one line ------------- */
static void downline()
{
if (lineno < wkw.wlines) {
if (wkw.wy == wkw.ht) {
scroll_window(1);
wkw.wtop++;
}
else
wkw.wy++;
}
else if (wkw.wlines <= wkw.ht)
firstline();
}

/* -------- move to the first line --------- */
static void firstline()
{
wkw.wtop = wkw.wy = 1;
}

/* -------- move to the last line --------- */
static void lastline()
{
wkw.wtop = wkw.wlines - (wkw.ht-1);
if (wkw.wtop < 1)
wkw.wtop = 1;
wkw.wy = wkw.ht;
if (wkw.wy > wkw.wlines)
wkw.wy = wkw.wlines;
}

char spaces[80] =
" ";
/* ------- display a line of text, highlight or normal ------ */
static void dline(ln, foreg, backg)
{
if (foreg || backg) {
textcolor(foreg);
textbackground(backg);
--ln;
writeline(2, ln-wkw.wtop+3, *(wkw.wtext + ln));
if (strlen(*(wkw.wtext + ln)) < wkw.wd-2)
writeline(2+strlen(*(wkw.wtext + ln)),
ln-wkw.wtop+3,
spaces + 79 - wkw.wd +
strlen(*(wkw.wtext + ln)) + 2 );
}
}

/* --------- write a line of text to video window ----------- */
void writeline(int x, int y, char *str)
{
int cl[80], *cp = cl;

while (*str)
*cp++ = (*str++ & 255) | (_video.attribute << 8);
__vram(__vptr(x+wkw.lf-1,y+wkw.tp-1),MK_FP(_DS,cl),cp-cl);
}

/* ------- use BIOS to hide the cursor ---------- */
void hidecursor()
{
rg.h.ah = 2;
rg.x.dx = 0x1900;
rg.h.bh = 0;
int86(0x10, &rg, &rg);
}

/* ----------- use BIOS to set the cursor type -------------- */
void set_cursor_type(unsigned t)
{
rg.x.ax = 0x0100;
rg.x.bx = 0;
rg.x.cx = t;
int86(0x10, &rg, &rg);
}

/* ----------- use BIOS to clear the screen ---------------- */
void clear_screen()
{
window(1,1,80,25);
gotoxy(1,1);
rg.h.al = ' ';
rg.h.ah = 9;
rg.x.bx = 7;
rg.x.cx = 2000;
int86(0x10, &rg, &rg);
}

void (*helpfunc)(void);
int helpkey;

/* ------------- read the keyboard ---------------- */
int getkey()
{
int c;

if ((c = getch()) == 0)
c = getch() | 128;
if (c == helpkey && helpfunc) {
(*helpfunc)();
c = getkey();
}
return c;
}

/* ------- write an error message ------------- */
void error_message(char *ermsg)
{
int lf = (80-strlen(ermsg)+2)/2;
int rt = lf+max(strlen(ermsg)+2,15);
establish_window(lf, 11, rt, 14, ERRORFG, ERRORBG, TRUE);
gotoxy(2,2);
cputs(ermsg);
gotoxy(2,3);
cputs("(Press [Esc])");
hidecursor();
do
putch(BELL);
while (getkey() != ESC);
delete_window();
}




  3 Responses to “Category : Files from Magazines
Archive   : DDJ0988.ZIP
Filename : STEVENS.LIS

  1. Very nice! Thank you for this wonderful archive. I wonder why I found it only now. Long live the BBS file archives!

  2. This is so awesome! 😀 I’d be cool if you could download an entire archive of this at once, though.

  3. But one thing that puzzles me is the “mtswslnkmcjklsdlsbdmMICROSOFT” string. There is an article about it here. It is definitely worth a read: http://www.os2museum.com/wp/mtswslnk/