Category : Recently Uploaded Files
Archive   : MSQ320.ZIP
Filename : WIN.C

 
Output of file : WIN.C contained in archive : MSQ320.ZIP
/* window.c
**
** released into the PUBLIC DOMAIN 10 jul 1994 by John Dennis
**
** This module contains routines that maintain text windows
** on the screen. Output routines are integrated in relation
** to the window coordinates on the screen. All coordinates
** have a 0 based origin! Please note this!
**
** This is the second level of abstraction from the physical
** device; it should not be necessary to modify this module
** when porting to other operating systems/devices.
**
** History:
** 10/11/91 JD Started.
** 25/07/92 JD Whole package (of which this is a module)
** was finished to a useable degree.
** 13/08/92 JD Functions added during the Msgedsq port to
** this system. Should increase the packages'
** useability.
**
*/

#define DEBUG 0
#define BAD_MOUSE 0

#include
#include
#include
#include
#include "winsys.h"
#include "keys.h"

#ifndef max
# define max(a,b) (((a) > (b)) ? (a) : (b))
#endif

#ifndef min
# define min(a,b) (((a) < (b)) ? (a) : (b))
#endif

/* prototypes */

void WDrwBox(int x1, int y1, int x2, int y2, unsigned char *Bdrc, int Battr, int ins);

/* these can olny be used on *existing* windows */

#define XMOD(w) ((w->flags & INSBDR) ? 3 : ((w->flags & NBDR) ? 0 : 1))
#define YMOD(w) ((w->flags & INSBDR) ? 2 : ((w->flags & NBDR) ? 0 : 1))


/*
** Local Variables.
**
*/

unsigned char Dbdr[6] = {'º', 'Í', 'É', '»', 'È', '¼'}; /* double border chars */
unsigned char Sbdr[6] = {'³', 'Ä', 'Ú', '¿', 'À', 'Ù'}; /* single border chars */
int FillChr = '±'; /* fill char for fields */
unsigned long wndid = 20; /* unique window ID */
WND *CW = NULL; /* current window */

static char line[255];


/*
** The Functions in the windowing library.
**
*/

int CheckMousePos(int x1, int y1, int x2, int y2)
{
int x, y;

GetMouInfo(&x, &y);
#if BAD_MOUSE
if (x >= x1 - 2 && x <= x2 + 2)
if (y >= y1 - 2 && y <= y2 + 3)
return 1;
#else
if (x >= x1 && x <= x2)
if (y >= y1 && y <= y2)
return 1;
#endif

return 0;
}

/*
**
** Creates and opens a window returning the handle to
** the user, using 0 based coordinates on the screen.
**
*/

WND *WndOpen(int x1, int y1, int x2, int y2, int Bdr, int BAttr, int Attr)
{
WND *w;
unsigned short ch;
int i, k = 0;

w = (WND *) malloc(sizeof(WND));

if (!w)
return NULL;

w->wid = ++wndid;
w->x1 = (unsigned char)x1;
w->x2 = (unsigned char)x2;
w->y1 = (unsigned char)y1;
w->y2 = (unsigned char)y2;
w->wattr = (unsigned char)Attr;
w->battr = (unsigned char)BAttr;
w->flags = (unsigned char)Bdr;
w->title = NULL;

if (Bdr & SHADOW)
{
x2 += 2;
y2++;
}

MouseOFF();

/* get a copy of the background */

if (!(Bdr & NOSAVE))
{
w->buffer = (unsigned short **)
malloc(sizeof(unsigned short *)*((y2 - y1) + 2));

if (!w->buffer)
return NULL;

for (i = y1;i <= y2; i++)
{
w->buffer[k] = (unsigned short *)
malloc(sizeof(unsigned short)*((x2 - x1) + 2));
if (!w->buffer[k])
{
return NULL;
}
TTReadStr(w->buffer[k], x2 - x1 + 1, i, x1);
k++;
}
}

/* Put out Shadow */

if (Bdr & SHADOW)
{
k = 1;
for (i = y1+1; i <= y2; i++)
{
ch = (unsigned short) w->buffer[k][x2 - x1];
ch &= 0x00FF;
ch |= ((unsigned short)(DGREY|_BLACK)<<8);
TTWriteStr(&ch, 1, i, x2);
ch = (unsigned short) w->buffer[k][x2 - x1 -1];
ch &= 0x00FF;
ch |= ((unsigned short)(DGREY|_BLACK)<<8);
TTWriteStr(&ch, 1, i, x2 - 1);
k++;
}
k = y2 - y1;
for (i = 2; i <= (x2 - x1); i++)
{
ch = (unsigned short) w->buffer[k][i];
ch &= 0x00FF;
ch |= ((unsigned short)(DGREY|_BLACK)<<8);
TTWriteStr(&ch, 1, y2, i+x1);
}
}

TTScolor(Attr);
TTClear(w->x1, w->y1, w->x2, w->y2);

if (!(Bdr & NBDR))
{
if (Bdr & SBDR)
{
WDrwBox(w->x1, w->y1, w->x2, w->y2, Sbdr, BAttr, (Bdr & INSBDR) ? 1 : 0);
}
else
{
WDrwBox(w->x1, w->y1, w->x2, w->y2, Dbdr, BAttr, (Bdr & INSBDR) ? 1 : 0);
}
}

MouseON();

return (CW = w);
}


/*
**
** Opens up a window of the passed size in
** the _middle_ of the screen.
**
*/

WND *WPopUp(int wid, int dep, int Bdr, int BAttr, int NAttr)
{
int x1, x2, y1, y2;

x1 = max(((term.NCol / 2) - (wid / 2) - 1), 0);
y1 = max(((term.NRow / 2) - (dep / 2) - 1), 0);
x2 = min(x1 + wid, term.NCol - 1);
y2 = min(y1 + dep, term.NRow - 1);

return WndOpen(x1, y1, x2, y2, Bdr, BAttr, NAttr);
}


/*
**
** Closes the passed window and restores the screen
** behind it.
**
** caveats: Since no track is kept of the windows
** on the screen, it is the caller's
** responsibility to ensure that windows
** are closed in the right order.
*/

void WClose(WND *w)
{
WND *wnd;
int i, k = 0;
int x2, y2;

/* restore screen buffer */

if (!w)
wnd = CW;
else
wnd = w;

if (!wnd)
return;

x2 = wnd->x2;
y2 = wnd->y2;

if (wnd->flags & SHADOW)
{
x2 += 2;
y2++;
}

MouseOFF();

if (!(wnd->flags & NOSAVE))
{
for (i = wnd->y1;i <= y2; i++)
{
TTWriteStr(wnd->buffer[k], x2 - wnd->x1 + 1, i, wnd->x1);
free(wnd->buffer[k++]);
}
free(wnd->buffer);
}
free(wnd);
MouseON();
wnd = NULL;
}



/*
**
** Draws a box at the specified position. Internal
** function (usually).
**
*/

void WDrwBox(int x1, int y1, int x2, int y2, unsigned char *Bdrc, int Battr, int ins)
{
unsigned int i;
unsigned short ch;
int xmod = (ins) ? 2 : 0;
int ymod = (ins) ? 1 : 0;

MouseOFF();
/* write top & bottom horiziontal border chars */

ch = (unsigned short)Bdrc[1] | (unsigned short)(Battr << 8);
for (i = x1 + 1 + xmod; i < x2 - xmod; i++) {
TTWriteStr(&ch, 1, y1+ymod, i);
}
for (i = x1 + 1 + xmod; i < x2 - xmod; i++) {
TTWriteStr(&ch, 1, y2-ymod, i);
}

/* write left & right vertical border chars */

ch = (unsigned short)Bdrc[0] | (unsigned short)(Battr << 8);
for (i = y1 + 1 + ymod; i < y2 - ymod; i++) {
TTWriteStr(&ch, 1, i, x1+xmod);
}
for (i = y1 + 1 + ymod; i < y2 - ymod; i++) {
TTWriteStr(&ch, 1, i, x2-xmod);
}

/* write corner chars */

ch = (unsigned short)Bdrc[2] | (unsigned short)(Battr << 8);
TTWriteStr(&ch, 1, y1+ymod, x1+xmod);

ch = (unsigned short)Bdrc[3] | (unsigned short)(Battr << 8);
TTWriteStr(&ch, 1, y1+ymod, x2-xmod);

ch = (unsigned short)Bdrc[4] | (unsigned short)(Battr << 8);
TTWriteStr(&ch, 1, y2-ymod, x1+xmod);

ch = (unsigned short)Bdrc[5] | (unsigned short)(Battr << 8);
TTWriteStr(&ch, 1, y2-ymod, x2-xmod);
MouseON();
return;
}


/*
**
** Draws a box in the window.
**
*/

void WBox(int x1, int y1, int x2, int y2, int Attr, int type)
{
int xmod, ymod;
unsigned char *Bdrc = (type & DBDR) ? Dbdr : Sbdr;

if (!CW) return;

ymod = YMOD(CW);
xmod = XMOD(CW);

if (y1 < 0 || x1 < 0)
return;

if ((CW->x1+ x2 + xmod) > CW->x2 || (CW->y1 + y2 + ymod) > CW->y2)
return;

WDrwBox(x1+CW->x1+xmod, y1+CW->y1+ymod,x2+CW->x1+xmod,y2+CW->y1+ymod,Bdrc,Attr,0);
}

/*
**
** Converts absolute coordinates to coordinates relative
** to the current window.
**
*/

void WndGetRel(int x, int y, int *wx, int *wy)
{
int xmod, ymod;
if (!CW) return;

ymod = YMOD(CW);
xmod = XMOD(CW);

*wx = x - (CW->x1 + xmod);
*wy = y - (CW->y1 + ymod);
}


int WndWidth(void)
{
if (!CW) return 0;

return ((CW->x2 - CW->x1) - (XMOD(CW)*2));
}


/*
**
** Writes a title to centre of the *current* window,
** clearing whatever wuz there in the first place.
**
** caveats: Doesn't check to see if there is a border,
** only for the type of border.
*/

void WTitle(char *Str, int Attr)
{
int cntr = (CW->x2 - CW->x1 + 1) / 2;
int pos, i, len = strlen(Str);
unsigned short ch;
int ymod;
unsigned char *Bdrc;
int m = 0;

if (!CW) return;

ymod = (CW->flags & INSBDR) ? 1 : 0; /* 'cause were writing on the border */

if (CheckMousePos(CW->x1, CW->y1, CW->x2, CW->y2))
{
m = 1;
MouseOFF();
}

if (CW->title) {
if (!(CW->flags & NBDR)) {
if (CW->flags & SBDR)
Bdrc = Sbdr;
else
Bdrc = Dbdr;
}
ch = (unsigned short)Bdrc[1] | (unsigned short)(CW->battr << 8);
for (i = CW->x1 + 1; i < CW->x2; i++) {
TTWriteStr(&ch, 1, CW->y1 + ymod, i);
}
free(CW->title);
}
pos = (cntr - (len/2)) + CW->x1;
CW->title = strdup(Str);

TTScolor(Attr);
TTStrWr((unsigned char *)Str, CW->y1 + ymod, pos);

if (m) MouseON();
}


/*
**
** Writes a string to the (current) window, using a 0
** based origin.
**
** caveats: If string would write past end of line,
** it won't write the string.
*/

void WWriteStr(int x, int y, int Attr, char *Str)
{
int row, col, len = strlen(Str);
int m = 0;
char *trunc, ch;

if (!CW) return;

row = CW->y1 + y; /* has to be 0 based */
col = CW->x1 + x; /* ditto */

if (!(CW->flags & NBDR))
{ /* check end-of-window overstep */
row += YMOD(CW);
col += XMOD(CW);
if (row >= CW->y2 || col > CW->x2 - XMOD(CW))
{
return;
}
}
else
{
if (row > CW->y2 || col > CW->x2)
return;
}
if (CheckMousePos(col, row, col + len - 1, row))
{
m = 1;
MouseOFF();
}
trunc = NULL;
if ((col + len - 1) > CW->x2 - XMOD(CW))
{
trunc = Str + ((CW->x2 - XMOD(CW)) - col + 1);
ch = *trunc;
*trunc = '\0';
}
TTScolor(Attr);
TTStrWr((unsigned char *)Str, row, col);

if (m)
MouseON();
if (trunc)
*trunc = ch;
}


/*
**
** Puts a string in the center of the window
** at the passed line.
**
*/

void WPutsCen(int y, int Attr, char *Str)
{
int cntr = (CW->x2 - CW->x1 + 1) / 2;
int col, len = strlen(Str);
int mod = XMOD(CW);

if (len > WndWidth())
col = 0;
else
col = cntr - (len / 2) - mod;
WWriteStr(col, y, Attr, Str);
}


/*
**
** Operates the same as printf(), except it
** does it to the current window, using the
** passed parameters.
**
*/

int WPrintf(int x, int y, int Attr, char *Str, ...)
{
va_list params;
int i;

va_start(params, Str);
i = vsprintf(line, Str, params);
WWriteStr(x, y, Attr, line);
return (i);
}


/*
**
** Puts len of Str onto the current window.
**
*/

void WPutsn(int x, int y, int len, int Attr, char *Str)
{
char *s = Str, *c = line;
int i = 0;

if (len > 254)
{
len = 254;
}

if (s != NULL)
{
i = strlen(s);
if (i > len)
{
i = len;
}
memcpy(c, s, i);
}

if (i < len)
{
memset(c + i, ' ', len - i);
}
c[len] = '\0';
WWriteStr(x, y, Attr, line);
}


/*
**
** Scrolls a window at the specified cooridiates
** using a 0 based origin.
**
** caveats: doesn't check for valid coordinates.
*/

void WScroll(int x1, int y1, int x2, int y2, int dir)
{
int xmod, ymod;
int m = 0;

if (!CW) return;

xmod = XMOD(CW);
ymod = YMOD(CW);

if (CheckMousePos(CW->x1+x1+xmod, CW->y1+y1+ymod, CW->x2+x2+xmod, CW->y2+y2+ymod))
{
m = 1;
MouseOFF();
}

TTScolor(CW->wattr);
TTScroll(CW->x1+x1+xmod, CW->y1+y1+ymod, CW->x1+x2+xmod, CW->y1+y2+ymod, 1, dir);
if (m) MouseON();
}


/*
**
** Makes the passed window the current window.
**
** caveats: The windowing system doesn't keep
** track of the windows that exist -
** the caller must do that...
*/

void WCurr(WND *hWnd)
{
if (CW == hWnd || hWnd == NULL)
return;

CW = hWnd;
}


/*/$/ WND* Wtop(void);
**
** Returns the current window recognized by
** the windowing system.
**
*/

WND* Wtop(void)
{
if (CW)
return CW;
else
return NULL;
}


/*
**
** Puts a char *anywhere* on the window, ignoring
** borders etc... Puts it at the current cursor
** position (virtual or real)...
**
** caveats: The cursor may not even be on the window,
** but it doesn't care 🙂
*/

void WPutc(int Ch, int Attr)
{
if (!CW) return;

MouseOFF();
TTScolor(Attr);
TTPutChr(Ch);
MouseON();
}


/*
**
** Goes to the passed coordinates, 0 based,
** starting from any borders on the window.
**
** caveats: No checks for validity of arguments.
*/

void Wgotoxy(int x, int y)
{
int xmod;
int ymod;

if (!CW) return;

xmod = XMOD(CW);
ymod = YMOD(CW);

TTgotoxy(CW->y1 + y + ymod, CW->x1 + x + xmod);
}


/*
**
** Clears the passed coordinates with the
** passed attribute in the current window.
**
** caveats: No checks for validity of arguments.
*/

void WClear(int x1, int y1, int x2, int y2, int attr)
{
int xmod;
int ymod;
int m = 0;

if (!CW) return;

xmod = XMOD(CW);
ymod = YMOD(CW);

if (CheckMousePos(CW->x1+x1+xmod, CW->y1+y1+ymod, CW->x2+x2+xmod, CW->y2+y2+ymod))
{
m = 1;
MouseOFF();
}
TTScolor(attr);
TTClear(CW->x1+x1+xmod, CW->y1+y1+ymod, CW->x1+x2+xmod, CW->y1+y2+ymod);
if (m) MouseON();
}

/*
**
** Clears the passed line in the current window.
**
*/

void WClearLine(int y, int Att)
{
if (!CW) return;

WClear(0, y, (CW->x2 - CW->x1) - (XMOD(CW)*2), y, Att);
}


/*
**
** Gets a string from the user on the current
** window at the passed coords. Passes mouse events
** not on itself back to the caller via the extra params. (sheesh!)
**
*/

/*
** Fills in an edit-field region with char.
*/

void WFillField(int x, int y, int len, unsigned char ch, int Attr)
{
if (len > 254) len = 254;

memset(line, ch, len);
*(line + len - 1) = '\0';
WWriteStr(x, y, Attr, line);
}

int WGetLine(int x, int y, int len, char *buf, int Attr, int *pos, int nokeys, int fil, int disp, EVT *ev)
{
EVT event;
int done = 0;
int row = y, col = x;
int xmod, ymod;
int i = 0;
unsigned int ch;
unsigned char fill = (fil) ? (unsigned char)FillChr : (unsigned char)' ';

if (!CW) return 0;

if (disp)
{
WFillField(col, row, len + 1, fill, Attr);
WPutsn(col, row, len, Attr, buf);
}

xmod = XMOD(CW);
ymod = YMOD(CW);

i = *pos;

TTCurSet(1);

while (!done)
{
Wgotoxy(i+col, row);
ch = MnuGetMsg(&event, 0);
switch (event.msgtype)
{
case WM_MOUSE:
case WM_COMMAND:
{
int p1 = event.x, p2 = event.y;
if (p1 < (CW->x1 + xmod + x) || p1 > (CW->x1 + xmod + x + len - 1) || p2 != (CW->y1 + ymod + y))
{
done = TRUE;
break;
}
}
break;
case WM_CHAR:
switch (ch)
{
case Key_Up:
case Key_Dwn:
done = TRUE;
break;
case Key_Lft:
if (i > 0)
i--;
nokeys = 0;
break;
case Key_Rgt:
if (i < strlen(buf))
i++;
nokeys = 0;
break;
case Key_A_X:
memset(buf, 0, len);
i = 0;
break;
case Key_BS :
if (i > 0) {
if (i < strlen(buf)) {
memmove(buf + i - 1, buf + i, strlen(buf + i) + 1);
i--;
WWriteStr(col + i, row, Attr, buf + i);
WPrintf(col + strlen(buf), row, Attr, "%c", fill);
}
else {
i--;
*(buf + i) = '\0';
Wgotoxy(i+col, row);
WPutc(fill, Attr);
}
}
nokeys = 0;
break;
case Key_Del:
if (i < strlen(buf)) {
memmove(buf + i, buf + i + 1, strlen(buf + i + 1) + 1);
WWriteStr(col + i, row, Attr, buf + i);
WPrintf(col + strlen(buf), row, Attr, "%c", fill);
}
nokeys = 0;
break;
case Key_End:
i = strlen(buf);
nokeys = 0;
break;
case Key_Home:
i = 0;
break;
case Key_Ent:
done = 1;
break;
case Key_Esc:
done = 2;
break;
default:
if (ch > 0 && i < len && strlen(buf) < len)
{
if (nokeys)
{
strcpy(buf, "");
WFillField(col, row, len + 1, fill, Attr);
i = 0;
Wgotoxy(i + col, row);
}

if (i < strlen(buf))
{
memmove(buf + i + 1, buf + i, strlen(buf + i) + 1);
*(buf + i) = (char)ch;
WWriteStr(col + i, row, Attr, buf + i);
i++;
}
else
{
*(buf + i) = (char)ch;
*(buf + i + 1) = '\0';
WPutc((unsigned char) ch , Attr);
i++;
}
}
else
{
done = 1;
}
break;
}
break;
}
nokeys = 0;
}
TTCurSet(0);

if (ev != NULL)
*ev = event;

*pos = i;
return ch;
}

#if DEBUG

int main(void)
{
WND *hWnd;

TTopen();
hWnd = WPopUp(30, 6, INSBDR|SHADOW, BLACK|_LGREY, BLACK|_LGREY);
WWriteStr(1, 1, BLACK|_LGREY, "Goto Message #?");
getch();
WClose(hWnd);
getch();
return (0);
}

#endif /* #if DEBUG (==1)*/

/* end of file */


  3 Responses to “Category : Recently Uploaded Files
Archive   : MSQ320.ZIP
Filename : WIN.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/