reactos/rosapps/dflat32/video.c
2003-06-19 02:48:13 +00:00

324 lines
6.9 KiB
C

/* --------------------- video.c -------------------- */
#include "dflat.h"
#define clr(fg,bg) ((fg)|((bg)<<4))
BOOL DfClipString;
/* -- read a rectangle of video memory into a save buffer -- */
void DfGetVideo(DFRECT rc, PCHAR_INFO bf)
{
COORD Size;
COORD Pos;
SMALL_RECT Rect;
Size.X = DfRectRight(rc) - DfRectLeft(rc) + 1;
Size.Y = DfRectBottom(rc) - DfRectTop(rc) + 1;
Pos.X = 0;
Pos.Y = 0;
Rect.Left = DfRectLeft(rc);
Rect.Top = DfRectTop(rc);
Rect.Right = DfRectRight(rc);
Rect.Bottom = DfRectBottom(rc);
ReadConsoleOutput (GetStdHandle (STD_OUTPUT_HANDLE),
bf,
Size,
Pos,
&Rect);
}
/* -- write a rectangle of video memory from a save buffer -- */
void DfStoreVideo(DFRECT rc, PCHAR_INFO bf)
{
COORD Size;
COORD Pos;
SMALL_RECT Rect;
Size.X = DfRectRight(rc) - DfRectLeft(rc) + 1;
Size.Y = DfRectBottom(rc) - DfRectTop(rc) + 1;
Pos.X = 0;
Pos.Y = 0;
Rect.Left = DfRectLeft(rc);
Rect.Top = DfRectTop(rc);
Rect.Right = DfRectRight(rc);
Rect.Bottom = DfRectBottom(rc);
WriteConsoleOutput (GetStdHandle (STD_OUTPUT_HANDLE),
bf,
Size,
Pos,
&Rect);
}
/* -------- read a character of video memory ------- */
char DfGetVideoChar(int x, int y)
{
COORD pos;
DWORD dwRead;
char ch;
pos.X = x;
pos.Y = y;
ReadConsoleOutputCharacter (GetStdHandle(STD_OUTPUT_HANDLE),
&ch,
1,
pos,
&dwRead);
return ch;
}
/* -------- write a character of video memory ------- */
void DfPutVideoChar(int x, int y, int ch)
{
COORD pos;
DWORD dwWritten;
if (x < DfScreenWidth && y < DfScreenHeight)
{
pos.X = x;
pos.Y = y;
WriteConsoleOutputCharacter (GetStdHandle(STD_OUTPUT_HANDLE),
(char *)&ch,
1,
pos,
&dwWritten);
}
}
BOOL DfCharInView(DFWINDOW wnd, int x, int y)
{
DFWINDOW nwnd = DfNextWindow(wnd);
DFWINDOW pwnd;
DFRECT rc;
int x1 = DfGetLeft(wnd)+x;
int y1 = DfGetTop(wnd)+y;
if (!DfTestAttribute(wnd, DF_VISIBLE))
return FALSE;
if (!DfTestAttribute(wnd, DF_NOCLIP))
{
DFWINDOW wnd1 = DfGetParent(wnd);
while (wnd1 != NULL)
{
/* clip character to parent's borders */
if (!DfTestAttribute(wnd1, DF_VISIBLE))
return FALSE;
if (!DfInsideRect(x1, y1, DfClientRect(wnd1)))
return FALSE;
wnd1 = DfGetParent(wnd1);
}
}
while (nwnd != NULL)
{
if (!isHidden(nwnd) && !DfIsAncestor(wnd, nwnd))
{
rc = DfWindowRect(nwnd);
if (DfTestAttribute(nwnd, DF_SHADOW))
{
DfRectBottom(rc)++;
DfRectRight(rc)++;
}
if (!DfTestAttribute(nwnd, DF_NOCLIP))
{
pwnd = nwnd;
while (DfGetParent(pwnd))
{
pwnd = DfGetParent(pwnd);
rc = DfSubRectangle(rc, DfClientRect(pwnd));
}
}
if (DfInsideRect(x1,y1,rc))
return FALSE;
}
nwnd = DfNextWindow(nwnd);
}
return (x1 < DfScreenWidth && y1 < DfScreenHeight);
}
/* -------- write a character to a window ------- */
void DfWPutch(DFWINDOW wnd, int c, int x, int y)
{
if (DfCharInView(wnd, x, y))
{
DWORD dwWritten;
COORD pos;
WORD Attr;
pos.X = DfGetLeft(wnd)+x;
pos.Y = DfGetTop(wnd)+y;
Attr = clr(DfForeground, DfBackground);
WriteConsoleOutputAttribute (GetStdHandle(STD_OUTPUT_HANDLE),
&Attr,
1,
pos,
&dwWritten);
WriteConsoleOutputCharacter (GetStdHandle(STD_OUTPUT_HANDLE),
(char *)&c,
1,
pos,
&dwWritten);
}
}
/* ------- write a string to a window ---------- */
void DfWPuts(DFWINDOW wnd, void *s, int x, int y)
{
int x1 = DfGetLeft(wnd)+x;
int x2 = x1;
int y1 = DfGetTop(wnd)+y;
if (x1 < DfScreenWidth && y1 < DfScreenHeight && DfIsVisible(wnd))
{
char ln[200];
WORD attr[200];
char *cp = ln;
WORD *ap = attr;
unsigned char *str = s;
int fg = DfForeground;
int bg = DfBackground;
int len;
int off = 0;
while (*str)
{
if (*str == DF_CHANGECOLOR)
{
str++;
DfForeground = (*str++) & 0x7f;
DfBackground = (*str++) & 0x7f;
continue;
}
if (*str == DF_RESETCOLOR)
{
DfForeground = fg & 0x7f;
DfBackground = bg & 0x7f;
str++;
continue;
}
*cp = (*str & 255);
*ap = (WORD)clr(DfForeground, DfBackground);
// *cp1 = (*str & 255) | (clr(DfForeground, DfBackground) << 8);
// if (DfClipString)
// if (!DfCharInView(wnd, x, y))
// *cp1 = peek(video_address, vad(x2,y1));
cp++;
ap++;
str++;
x++;
x2++;
}
DfForeground = fg;
DfBackground = bg;
len = (int)(cp-ln);
if (x1+len > DfScreenWidth)
len = DfScreenWidth-x1;
if (!DfClipString && !DfTestAttribute(wnd, DF_NOCLIP))
{
/* -- clip the line to DfWithin ancestor windows -- */
DFRECT rc = DfWindowRect(wnd);
DFWINDOW nwnd = DfGetParent(wnd);
while (len > 0 && nwnd != NULL)
{
if (!DfIsVisible(nwnd))
{
len = 0;
break;
}
rc = DfSubRectangle(rc, DfClientRect(nwnd));
nwnd = DfGetParent(nwnd);
}
while (len > 0 && !DfInsideRect(x1+off,y1,rc))
{
off++;
--len;
}
if (len > 0)
{
x2 = x1+len-1;
while (len && !DfInsideRect(x2,y1,rc))
{
--x2;
--len;
}
}
}
if (len > 0)
{
COORD pos;
DWORD dwWritten;
pos.X = x1;
pos.Y = y1;
WriteConsoleOutputAttribute (GetStdHandle(STD_OUTPUT_HANDLE),
attr,
len,
pos,
&dwWritten);
WriteConsoleOutputCharacter (GetStdHandle(STD_OUTPUT_HANDLE),
ln,
len,
pos,
&dwWritten);
}
}
}
/* --------- scroll the window. d: 1 = up, 0 = dn ---------- */
void DfScrollWindow(DFWINDOW wnd, DFRECT rc, int d)
{
if (DfRectTop(rc) != DfRectBottom(rc))
{
CHAR_INFO ciFill;
SMALL_RECT rcScroll;
SMALL_RECT rcClip;
COORD pos;
ciFill.Attributes = clr(DfWndForeground(wnd),DfWndBackground(wnd));
ciFill.Char.AsciiChar = ' ';
rcScroll.Left = DfRectLeft(rc);
rcScroll.Right = DfRectRight(rc);
rcScroll.Top = DfRectTop(rc);
rcScroll.Bottom = DfRectBottom(rc);
rcClip = rcScroll;
pos.X = DfRectLeft(rc);
if (d == 0)
{
/* scroll 1 line down */
pos.Y = DfRectTop(rc)+1;
}
else
{
/* scroll 1 line up */
pos.Y = DfRectTop(rc)-1;
}
ScrollConsoleScreenBuffer (GetStdHandle(STD_OUTPUT_HANDLE),
&rcScroll,
&rcClip,
pos,
&ciFill);
}
}
/* EOF */