home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Current Shareware 1994 January
/
SHAR194.ISO
/
catalogs
/
mtchplay.zip
/
WINDOW.C
< prev
next >
Wrap
Text File
|
1992-09-20
|
9KB
|
415 lines
/* -------------- window.c ----------------------- */
/* From DDJ, September 1988 */
#include <stdio.h>
#include <alloc.h>
#include <string.h>
#include <conio.h>
#include <mem.h>
#include <dos.h>
#include <stdlib.h>
#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 window area, display 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,wkw.rt-1,wkw.bt-2+d,wkw.lf+1,wkw.tp+2-d);
else
{
rg.h.ah = d ? 6 : 7;
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 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 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 = get_key();
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 first line ------------------------- */
static void firstline()
{
wkw.wtop = wkw.wy = 1;
}
/* ---------------------- move to 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 c1[80], *cp = c1;
while (*str)
*cp++ = (*str++ & 255) | (_video.attribute << 8);
__vram(__vptr(x+wkw.lf-1,y+wkw.tp-1),(int far *)c1,
(unsigned)((int far *)cp-(int far *)c1));
}
/* ---------------- hide the cursor ----------------- */
void hidecursor()
{
rg.h.ah = 2;
rg.x.dx = 0x1900;
rg.h.bh = 0;
int86(0x10,&rg,&rg);
}
/* ----------------- set cursor type ------------------ */
void set_cursor_type(unsigned t)
{
rg.x.ax = 0x0100;
rg.x.bx = 0;
rg.x.cx = t;
int86(0x10,&rg,&rg);
}
/* ------------------ clear 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 keyboard ----------------------- */
int get_key()
{
int c;
if ((c=getch()) == 0)
c = getch() | 128;
if (c == helpkey && helpfunc)
{
(*helpfunc)();
c = get_key();
}
return c;
}
/* -------------------- write error message -------------------- */
void error_message(char *errmsg)
{
int lf = (80-strlen(errmsg)+2)/2;
int rt = lf + max(strlen(errmsg)+2,15);
establish_window(lf,11,rt,14,ERRORFG,ERRORBG,TRUE);
gotoxy(2,2);
cputs(errmsg);
gotoxy(2,3);
cputs("(Press [Esc])");
hidecursor();
putch(BELL);
while (get_key() != ESC)
;
delete_window();
}