Category : Files from Magazines
Archive   : DDJSRC.ZIP
Filename : WINDOW.C

 
Output of file : WINDOW.C contained in archive : DDJSRC.ZIP
/* ----------------------- 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),(int far*) cl,(unsigned)((int far*) cp - (int far*) 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   : DDJSRC.ZIP
Filename : WINDOW.C

  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/