home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Power-Programmierung
/
CD1.mdf
/
magazine
/
drdobbs
/
1991
/
08
/
c_prog.asc
< prev
next >
Wrap
Text File
|
1991-07-23
|
33KB
|
922 lines
_C PROGRAMMING COLUMN_
by Al Stevens
[LISTING ONE]
/* ------------- dflat.h ----------- */
#ifndef WINDOW_H
#define WINDOW_H
#define VERSION "Version 3 Beta"
#define TRUE 1
#define FALSE 0
#include "system.h"
#include "config.h"
#include "rect.h"
#include "menu.h"
#include "keys.h"
#include "commands.h"
#include "config.h"
#include "dialbox.h"
/* ------ integer type for message parameters ----- */
typedef long PARAM;
#define TE(m) m
typedef enum window_class {
#include "classes.h"
} CLASS;
typedef struct window {
CLASS class; /* window class */
char *title; /* window title */
struct window *parent; /* parent window */
int (*wndproc)
(struct window *, enum messages, PARAM, PARAM);
/* ---------------- window dimensions ----------------- */
RECT rc; /* window coordinates (0/0 to 79/24) */
int ht, wd; /* window height and width */
RECT RestoredRC; /* restored condition rect */
/* -------------- linked list pointers ---------------- */
struct window *next; /* next window on screen */
struct window *prev; /* previous window on screen*/
struct window *nextbuilt; /* next window built */
struct window *prevbuilt; /* previous window built */
int attrib; /* Window attributes */
char *videosave; /* video save buffer */
int condition; /* Restored, Maximized, Minimized */
int restored_attrib; /* attributes when restored */
void *extension; /* -> menus, dialog box, etc*/
struct window *PrevMouse;
struct window *PrevKeyboard;
/* ----------------- text box fields ------------------ */
int wlines; /* number of lines of text */
int wtop; /* text line that is on the top display */
char *text; /* window text */
int textlen; /* text length */
int wleft; /* left position in window viewport */
int textwidth; /* width of longest line in textbox */
int BlkBegLine; /* beginning line of marked block */
int BlkBegCol; /* beginning column of marked block */
int BlkEndLine; /* ending line of marked block */
int BlkEndCol; /* ending column of marked block */
int HScrollBox; /* position of horizontal scroll box */
int VScrollBox; /* position of vertical scroll box */
/* ----------------- list box fields ------------------ */
int selection; /* current selection */
int AddMode; /* adding extended selections mode */
int AnchorPoint;/* anchor point for extended selections */
int SelectCount;/* count of selected items */
/* ----------------- edit box fields ------------------ */
int CurrCol; /* Current column */
int CurrLine; /* Current line */
int WndRow; /* Current window row */
int TextChanged; /* TRUE if text has changed */
char *DeletedText; /* for undo */
int DeletedLength; /* " " */
/* ---------------- dialog box fields ----------------- */
struct window *dFocus; /* control that has the focus */
int ReturnCode; /* return code from a dialog box */
} * WINDOW;
#include "message.h"
#include "classdef.h"
#include "video.h"
enum Condition {
ISRESTORED, ISMINIMIZED, ISMAXIMIZED
};
void LogMessages (WINDOW, MESSAGE, PARAM, PARAM);
void MessageLog(WINDOW);
/* ------- window methods ----------- */
#define WindowHeight(w) ((w)->ht)
#define WindowWidth(w) ((w)->wd)
#define BorderAdj(w) (TestAttribute(w,HASBORDER)?1:0)
#define TopBorderAdj(w) ((TestAttribute(w,TITLEBAR) && \
TestAttribute(w,HASMENUBAR)) ? \
2 : (TestAttribute(w,TITLEBAR | \
HASMENUBAR | HASBORDER) ? 1 : 0))
#define ClientWidth(w) (WindowWidth(w)-BorderAdj(w)*2)
#define ClientHeight(w) (WindowHeight(w)-TopBorderAdj(w)-\
BorderAdj(w))
#define WindowRect(w) ((w)->rc)
#define GetTop(w) (RectTop(WindowRect(w)))
#define GetBottom(w) (RectBottom(WindowRect(w)))
#define GetLeft(w) (RectLeft(WindowRect(w)))
#define GetRight(w) (RectRight(WindowRect(w)))
#define GetClientTop(w) (GetTop(w)+TopBorderAdj(w))
#define GetClientBottom(w) (GetBottom(w)-BorderAdj(w))
#define GetClientLeft(w) (GetLeft(w)+BorderAdj(w))
#define GetClientRight(w) (GetRight(w)-BorderAdj(w))
#define GetParent(w) ((w)->parent)
#define GetTitle(w) ((w)->title)
#define NextWindow(w) ((w)->next)
#define PrevWindow(w) ((w)->prev)
#define NextWindowBuilt(w) ((w)->nextbuilt)
#define PrevWindowBuilt(w) ((w)->prevbuilt)
#define GetClass(w) ((w)->class)
#define GetAttribute(w) ((w)->attrib)
#define AddAttribute(w,a) (GetAttribute(w) |= a)
#define ClearAttribute(w,a) (GetAttribute(w) &= ~(a))
#define TestAttribute(w,a) (GetAttribute(w) & (a))
#define isVisible(w) (GetAttribute(w) & VISIBLE)
#define SetVisible(w) (GetAttribute(w) |= VISIBLE)
#define ClearVisible(w) (GetAttribute(w) &= ~VISIBLE)
#define gotoxy(w,x,y) cursor(w->rc.lf+(x)+1,w->rc.tp+(y)+1)
WINDOW CreateWindow(CLASS,char *,int,int,int,int,void*,WINDOW,
int (*)(struct window *,enum messages,PARAM,PARAM),int);
void AddTitle(WINDOW, char *);
void InsertTitle(WINDOW, char *);
void DisplayTitle(WINDOW, RECT *);
void RepaintBorder(WINDOW, RECT *);
void ClearWindow(WINDOW, RECT *, int);
#ifdef INCLUDE_SYSTEM_MENUS
void clipline(WINDOW, int, char *);
#else
#define clipline(w,x,c) /**/
#endif
void writeline(WINDOW, char *, int, int, int);
void writefull(WINDOW, char *, int);
void SetNextFocus(WINDOW,int);
void SetPrevFocus(WINDOW,int);
void PutWindowChar(WINDOW, int, int, int);
void GetVideoBuffer(WINDOW);
void RestoreVideoBuffer(WINDOW);
void CreatePath(char *, char *, int, int);
int LineLength(char *);
RECT AdjustRectangle(WINDOW, RECT);
#define DisplayBorder(wnd) RepaintBorder(wnd, NULL)
#define DefaultWndProc(wnd,msg,p1,p2) \
(*classdefs[FindClass(wnd->class)].wndproc)(wnd,msg,p1,p2)
#define BaseWndProc(class,wnd,msg,p1,p2) \
(*classdefs[DerivedClass(class)].wndproc)(wnd,msg,p1,p2)
#define NULLWND ((WINDOW) 0)
struct LinkedList {
WINDOW FirstWindow;
WINDOW LastWindow;
};
extern struct LinkedList Focus;
extern struct LinkedList Built;
extern WINDOW inFocus;
extern WINDOW CaptureMouse;
extern WINDOW CaptureKeyboard;
extern int foreground, background;
extern int WindowMoving;
extern int WindowSizing;
extern int TextMarking;
extern char *Clipboard;
extern WINDOW SystemMenuWnd;
/* --------------- border characters ------------- */
#define FOCUS_NW '\xc9'
#define FOCUS_NE '\xbb'
#define FOCUS_SE '\xbc'
#define FOCUS_SW '\xc8'
#define FOCUS_SIDE '\xba'
#define FOCUS_LINE '\xcd'
#define NW '\xda'
#define NE '\xbf'
#define SE '\xd9'
#define SW '\xc0'
#define SIDE '\xb3'
#define LINE '\xc4'
#define LEDGE '\xc3'
#define REDGE '\xb4'
/* ------------- scroll bar characters ------------ */
#define UPSCROLLBOX '\x1e'
#define DOWNSCROLLBOX '\x1f'
#define LEFTSCROLLBOX '\x11'
#define RIGHTSCROLLBOX '\x10'
#define SCROLLBARCHAR 176
#define SCROLLBOXCHAR 178
#define CHECKMARK 251 /* menu item toggle */
/* ----------------- title bar characters ----------------- */
#define CONTROLBOXCHAR '\xf0'
#define MAXPOINTER 24 /* maximize token */
#define MINPOINTER 25 /* minimize token */
#define RESTOREPOINTER 18 /* restore token */
/* --------------- text control characters ---------------- */
#define APPLCHAR 176 /* fills application window */
#define SHORTCUTCHAR '~' /* prefix: shortcut key display */
#define CHANGECOLOR 174 /* prefix to change colors */
#define RESETCOLOR 175 /* reset colors to default */
#define LISTSELECTOR 4 /* selected list box entry */
/* ---- standard window message processing prototypes ----- */
int ApplicationProc(WINDOW, MESSAGE, PARAM, PARAM);
int NormalProc(WINDOW, MESSAGE, PARAM, PARAM);
int TextBoxProc(WINDOW, MESSAGE, PARAM, PARAM);
int ListBoxProc(WINDOW, MESSAGE, PARAM, PARAM);
int EditBoxProc(WINDOW, MESSAGE, PARAM, PARAM);
int MenuBarProc(WINDOW, MESSAGE, PARAM, PARAM);
int PopDownProc(WINDOW, MESSAGE, PARAM, PARAM);
int ButtonProc(WINDOW, MESSAGE, PARAM, PARAM);
int DialogProc(WINDOW, MESSAGE, PARAM, PARAM);
int SystemMenuProc(WINDOW, MESSAGE, PARAM, PARAM);
int HelpBoxProc(WINDOW, MESSAGE, PARAM, PARAM);
int MessageBoxProc(WINDOW, MESSAGE, PARAM, PARAM);
/* ------------- normal box prototypes ------------- */
int isWindow(WINDOW);
WINDOW inWindow(int, int);
int WndForeground(WINDOW);
int WndBackground(WINDOW);
int FrameForeground(WINDOW);
int FrameBackground(WINDOW);
int SelectForeground(WINDOW);
int SelectBackground(WINDOW);
void SetStandardColor(WINDOW);
void SetReverseColor(WINDOW);
void SetClassColors(CLASS);
WINDOW GetFirstChild(WINDOW);
WINDOW GetNextChild(WINDOW);
WINDOW GetLastChild(WINDOW);
WINDOW GetPrevChild(WINDOW);
#define HitControlBox(wnd, p1, p2) \
(TestAttribute(wnd, TITLEBAR) && \
TestAttribute(wnd, CONTROLBOX) && \
p1 == 2 && p2 == 0)
/* -------- text box prototypes ---------- */
#define TextLine(wnd, sel) \
(wnd->text + *((int *)(wnd->extension) + sel))
void WriteTextLine(WINDOW, RECT *, int, int);
void SetAnchor(WINDOW, int, int);
#define BlockMarked(wnd) ( wnd->BlkBegLine || \
wnd->BlkEndLine || \
wnd->BlkBegCol || \
wnd->BlkEndCol)
#define ClearBlock(wnd) wnd->BlkBegLine = wnd->BlkEndLine = \
wnd->BlkBegCol = wnd->BlkEndCol = 0;
#define GetText(w) ((w)->text)
void ClearTextPointers(WINDOW);
void BuildTextPointers(WINDOW);
/* --------- menu prototypes ---------- */
int CopyCommand(char *, char *, int, int);
void PrepOptionsMenu(void *, struct Menu *);
void PrepEditMenu(void *, struct Menu *);
void PrepWindowMenu(void *, struct Menu *);
void BuildSystemMenu(WINDOW);
int isActive(MENU *, int);
void ActivateCommand(MENU *,int);
void DeactivateCommand(MENU *,int);
int GetCommandToggle(MENU *,int);
void SetCommandToggle(MENU *,int);
void ClearCommandToggle(MENU *,int);
void InvertCommandToggle(MENU *,int);
/* ------------- list box prototypes -------------- */
int ItemSelected(WINDOW, int);
/* ------------- edit box prototypes ----------- */
#ifdef INCLUDE_MULTILINE
#define isMultiLine(wnd) TestAttribute(wnd, MULTILINE)
#else
#define isMultiLine(wnd) FALSE
#endif
/* --------- message box prototypes -------- */
void MessageBox(char *, char *);
void ErrorMessage(char *);
int TestErrorMessage(char *);
int YesNoBox(char *);
int MsgHeight(char *);
int MsgWidth(char *);
#ifdef INCLUDE_DIALOG_BOXES
/* ------------- dialog box prototypes -------------- */
int DialogBox(WINDOW,DBOX *,int(*)(struct window *,enum messages,PARAM,PARAM));
int DlgOpenFile(char *, char *);
int DlgSaveAs(char *);
void GetDlgListText(WINDOW, char *, enum commands);
int DlgDirList(WINDOW, char *, enum commands, enum commands, unsigned);
int RadioButtonSetting(DBOX *, enum commands);
void PushRadioButton(DBOX *, enum commands);
void PutItemText(WINDOW, enum commands, char *);
void GetItemText(WINDOW, enum commands, char *, int);
void SetCheckBox(DBOX *, enum commands);
void ClearCheckBox(DBOX *, enum commands);
int CheckBoxSetting(DBOX *, enum commands);
WINDOW ControlWindow(DBOX *, enum commands);
CTLWINDOW *ControlBox(DBOX *, WINDOW);
#endif
/* ------------- help box prototypes ------------- */
void HelpFunction(void);
void LoadHelpFile(void);
#define swap(a,b){int x=a;a=b;b=x;}
#endif
[LISTING TWO]
/* ---------------- config.h -------------- */
#ifndef CONFIG_H
#define CONFIG_H
#define DFLAT_APPLICATION "MEMOPAD"
#ifdef BUILD_FULL_DFLAT
#define INCLUDE_SYSTEM_MENUS
#define INCLUDE_CLOCK
#define INCLUDE_MULTIDOCS
#define INCLUDE_SCROLLBARS
#define INCLUDE_SHADOWS
#define INCLUDE_DIALOG_BOXES
#define INCLUDE_CLIPBOARD
#define INCLUDE_MULTILINE
#define INCLUDE_LOGGING
#endif
struct colors {
/* ------------ colors ------------ */
char ApplicationFG, ApplicationBG;
char NormalFG, NormalBG;
char ButtonFG, ButtonBG;
char ButtonSelFG, ButtonSelBG;
char DialogFG, DialogBG;
char ErrorBoxFG, ErrorBoxBG;
char MessageBoxFG, MessageBoxBG;
char HelpBoxFG, HelpBoxBG;
char InFocusTitleFG, InFocusTitleBG;
char TitleFG, TitleBG;
char DummyFG, DummyBG;
char TextBoxFG, TextBoxBG;
char TextBoxSelFG, TextBoxSelBG;
char TextBoxFrameFG, TextBoxFrameBG;
char ListBoxFG, ListBoxBG;
char ListBoxSelFG, ListBoxSelBG;
char ListBoxFrameFG, ListBoxFrameBG;
char EditBoxFG, EditBoxBG;
char EditBoxSelFG, EditBoxSelBG;
char EditBoxFrameFG, EditBoxFrameBG;
char MenuBarFG, MenuBarBG;
char MenuBarSelFG, MenuBarSelBG;
char PopDownFG, PopDownBG;
char PopDownSelFG, PopDownSelBG;
char InactiveSelFG;
char ShortCutFG;
};
/* ----------- configuration parameters ----------- */
typedef struct config {
char version[sizeof DFLAT_APPLICATION + sizeof VERSION];
char mono; /* 0=color, 1=mono, 2=reverse mono */
int InsertMode; /* Editor insert mode */
int Tabs; /* Editor tab stops */
int WordWrap; /* True to word wrap editor */
int Border; /* True for application window border */
int Title; /* True for application window title */
int Texture; /* True for textured appl window */
int ScreenLines; /* Number of screen lines (25/43/50) */
struct colors clr; /* Colors */
} CONFIG;
extern CONFIG cfg;
extern struct colors color, bw, reverse;
int LoadConfig(void);
void SaveConfig(void);
#endif
[LISTING THREE]
/* ---------- window.c ------------- */
#include <stdio.h>
#include <conio.h>
#include <stdlib.h>
#include <string.h>
#include <dos.h>
#include "dflat.h"
WINDOW inFocus = NULLWND;
int foreground, background; /* current video colors */
static void TopLine(WINDOW, int, RECT);
/* --------- create a window ------------ */
WINDOW CreateWindow(
CLASS class, /* class of this window */
char *ttl, /* title or NULL */
int left, int top, /* upper left coordinates */
int height, int width, /* dimensions */
void *extension, /* pointer to additional data */
WINDOW parent, /* parent of this window */
int (*wndproc)(struct window *,enum messages,PARAM,PARAM),
int attrib) /* window attribute */
{
WINDOW wnd = malloc(sizeof(struct window));
get_videomode();
if (wnd != NULLWND) {
int base;
/* ----- height, width = -1: fill the screen ------- */
if (height == -1)
height = SCREENHEIGHT;
if (width == -1)
width = SCREENWIDTH;
/* ----- coordinates -1, -1 = center the window ---- */
if (left == -1)
wnd->rc.lf = (SCREENWIDTH-width)/2;
else
wnd->rc.lf = left;
if (top == -1)
wnd->rc.tp = (SCREENHEIGHT-height)/2;
else
wnd->rc.tp = top;
wnd->attrib = attrib;
if (ttl != NULL)
AddAttribute(wnd, TITLEBAR);
if (wndproc == NULL)
wnd->wndproc = classdefs[FindClass(class)].wndproc;
else
wnd->wndproc = wndproc;
/* ---- derive attributes of base classes ---- */
base = class;
while (base != -1) {
int tclass = FindClass(base);
AddAttribute(wnd, classdefs[tclass].attrib);
base = classdefs[tclass].base;
}
if (parent && !TestAttribute(wnd, NOCLIP)) {
/* -- keep upper left within borders of parent - */
wnd->rc.lf = max(wnd->rc.lf,GetClientLeft(parent));
wnd->rc.tp = max(wnd->rc.tp,GetClientTop(parent));
}
wnd->class = class;
wnd->extension = extension;
wnd->rc.rt = GetLeft(wnd)+width-1;
wnd->rc.bt = GetTop(wnd)+height-1;
wnd->ht = height;
wnd->wd = width;
wnd->title = NULL;
if (ttl != NULL)
InsertTitle(wnd, ttl);
wnd->next = wnd->prev = wnd->dFocus = NULLWND;
wnd->parent = parent;
wnd->videosave = NULL;
wnd->condition = ISRESTORED;
wnd->restored_attrib = 0;
wnd->RestoredRC = wnd->rc;
wnd->PrevKeyboard = wnd->PrevMouse = NULL;
wnd->DeletedText = NULL;
SendMessage(wnd, CREATE_WINDOW, 0, 0);
if (isVisible(wnd))
SendMessage(wnd, SHOW_WINDOW, 0, 0);
}
return wnd;
}
/* -------- add a title to a window --------- */
void AddTitle(WINDOW wnd, char *ttl)
{
InsertTitle(wnd, ttl);
SendMessage(wnd, BORDER, 0, 0);
}
/* ----- insert a title into a window ---------- */
void InsertTitle(WINDOW wnd, char *ttl)
{
if ((wnd->title=realloc(wnd->title,strlen(ttl)+1)) != NULL)
strcpy(wnd->title, ttl);
}
/* ------- write a character to a window area at x,y ------- */
void PutWindowChar(WINDOW wnd, int x, int y, int c)
{
int x1 = GetLeft(wnd)+x;
int y1 = GetTop(wnd)+y;
if (isVisible(wnd)) {
if (!TestAttribute(wnd, NOCLIP)) {
WINDOW wnd1 = GetParent(wnd);
while (wnd1 != NULLWND) {
/* --- clip character to parent's borders -- */
if (x1 < GetClientLeft(wnd1) ||
x1 > GetClientRight(wnd1) ||
y1 > GetClientBottom(wnd1) ||
y1 < GetClientTop(wnd1))
return;
wnd1 = GetParent(wnd1);
}
}
if (x1 < SCREENWIDTH && y1 < SCREENHEIGHT)
wputch(wnd, c, x, y);
}
}
static char line[161];
#ifdef INCLUDE_SYSTEM_MENUS
/* ----- clip line if it extends below the bottom of parent window ------ */
static int clipbottom(WINDOW wnd, int y)
{
if (!TestAttribute(wnd, NOCLIP)) {
WINDOW wnd1 = GetParent(wnd);
while (wnd1 != NULLWND) {
if (GetClientTop(wnd)+y > GetClientBottom(wnd1)+1)
return TRUE;
wnd1 = GetParent(wnd1);
}
}
return GetTop(wnd)+y > SCREENHEIGHT;
}
/* -- clip portion of line that extends past right margin of parent window-- */
void clipline(WINDOW wnd, int x, char *ln)
{
WINDOW pwnd = GetParent(wnd);
int x1 = strlen(ln);
int i = 0;
if (!TestAttribute(wnd, NOCLIP)) {
while (pwnd != NULLWND) {
x1 = GetClientRight(pwnd) - GetLeft(wnd) - x + 1;
pwnd = GetParent(pwnd);
}
}
else if (GetLeft(wnd) + x > SCREENWIDTH)
x1 = SCREENWIDTH-GetLeft(wnd) - x;
/* --- adjust the clipping offset for color controls --- */
if (x1 < 0)
x1 = 0;
while (i < x1) {
if ((unsigned char) ln[i] == CHANGECOLOR)
i += 3, x1 += 3;
else if ((unsigned char) ln[i] == RESETCOLOR)
i++, x1++;
else
i++;
}
ln[x1] = '\0';
}
#else
#define clipbottom(w,y) FALSE
#endif
/* ------ write a line to video window client area ------ */
void writeline(WINDOW wnd, char *str, int x, int y, int pad)
{
static char wline[120];
if (!clipbottom(wnd, y))
{
char *cp;
int len;
int dif;
memset(wline, 0, sizeof wline);
len = LineLength(str);
dif = strlen(str) - len;
strncpy(wline, str, ClientWidth(wnd) + dif);
if (pad) {
cp = wline+strlen(wline);
while (len++ < ClientWidth(wnd)-x)
*cp++ = ' ';
}
clipline(wnd, x, wline);
wputs(wnd, wline, x, y);
}
}
/* -- write a line to video window (including the border) -- */
void writefull(WINDOW wnd, char *str, int y)
{
if (!clipbottom(wnd, y)) {
strcpy(line, str);
clipline(wnd, 0, line);
wputs(wnd, line, 0, y);
}
}
RECT AdjustRectangle(WINDOW wnd, RECT rc)
{
/* -------- adjust the rectangle ------- */
if (TestAttribute(wnd, HASBORDER)) {
if (RectLeft(rc) == 0)
--rc.rt;
else if (RectLeft(rc) < RectRight(rc) &&
RectLeft(rc) < WindowWidth(wnd)+1)
--rc.lf;
}
if (TestAttribute(wnd, HASBORDER | TITLEBAR)) {
if (RectTop(rc) == 0)
--rc.bt;
else if (RectTop(rc) < RectBottom(rc) &&
RectTop(rc) < WindowHeight(wnd)+1)
--rc.tp;
}
RectRight(rc) = max(RectLeft(rc),min(RectRight(rc),WindowWidth(wnd)));
RectBottom(rc) = max(RectTop(rc),min(RectBottom(rc),WindowHeight(wnd)));
return rc;
}
/* -------- display a window's title --------- */
void DisplayTitle(WINDOW wnd, RECT *rcc)
{
int tlen = min(strlen(wnd->title), WindowWidth(wnd)-2);
int tend = WindowWidth(wnd)-3-BorderAdj(wnd);
RECT rc;
if (rcc == NULL)
rc = RelativeWindowRect(wnd, WindowRect(wnd));
else
rc = *rcc;
rc = AdjustRectangle(wnd, rc);
if (SendMessage(wnd, TITLE, LPARAM(rcc), 0)) {
if (wnd == inFocus) {
foreground = cfg.clr.InFocusTitleFG;
background = cfg.clr.InFocusTitleBG;
}
else {
foreground = cfg.clr.TitleFG;
background = cfg.clr.TitleBG;
}
memset(line,' ',WindowWidth(wnd));
if (wnd->condition != ISMINIMIZED)
strncpy(line + ((WindowWidth(wnd)-2 - tlen) / 2),
wnd->title, tlen);
if (TestAttribute(wnd, CONTROLBOX))
line[2-BorderAdj(wnd)] = CONTROLBOXCHAR;
#ifdef INCLUDE_SYSTEM_MENUS
if (TestAttribute(wnd, MINMAXBOX)) {
switch (wnd->condition) {
case ISRESTORED:
line[tend+1] = MAXPOINTER;
line[tend] = MINPOINTER;
break;
case ISMINIMIZED:
line[tend+1] = MAXPOINTER;
break;
case ISMAXIMIZED:
line[tend] = MINPOINTER;
line[tend+1] = RESTOREPOINTER;
break;
default:
break;
}
}
#endif
line[RectRight(rc)+1] = line[tend+3] = '\0';
writeline(wnd, line+RectLeft(rc),
RectLeft(rc)+BorderAdj(wnd),
0,
FALSE);
}
}
#ifdef INCLUDE_SHADOWS
/* --- display right border shadow character of a window --- */
static void near shadow_char(WINDOW wnd, int y)
{
int fg = foreground;
int bg = background;
int x = WindowWidth(wnd);
int c = videochar(GetLeft(wnd)+x, GetTop(wnd)+y);
if (TestAttribute(wnd, SHADOW) == 0)
return;
foreground = DARKGRAY;
background = BLACK;
PutWindowChar(wnd, x, y, c);
foreground = fg;
background = bg;
}
/* --- display the bottom border shadow line for a window -- */
static void near shadowline(WINDOW wnd, RECT rc)
{
int i;
int y = GetBottom(wnd)+1;
if ((TestAttribute(wnd, SHADOW)) == 0)
return;
if (!clipbottom(wnd, WindowHeight(wnd))) {
int fg = foreground;
int bg = background;
for (i = 0; i < WindowWidth(wnd)+1; i++)
line[i] = videochar(GetLeft(wnd)+i, y);
line[i] = '\0';
foreground = DARKGRAY;
background = BLACK;
clipline(wnd, 1, line);
line[RectRight(rc)+1] = '\0';
if (RectLeft(rc) == 0)
rc.lf++;
wputs(wnd, line+RectLeft(rc), RectLeft(rc),WindowHeight(wnd));
foreground = fg;
background = bg;
}
}
#endif
/* ------- display a window's border ----- */
void RepaintBorder(WINDOW wnd, RECT *rcc)
{
int y;
int lin, side, ne, nw, se, sw;
RECT rc, clrc;
if (!TestAttribute(wnd, HASBORDER))
return;
if (rcc == NULL) {
rc = RelativeWindowRect(wnd, WindowRect(wnd));
#ifdef INCLUDE_SHADOWS
if (TestAttribute(wnd, SHADOW)) {
rc.rt++;
rc.bt++;
}
#endif
}
else
rc = *rcc;
clrc = AdjustRectangle(wnd, rc);
if (wnd == inFocus) {
lin = FOCUS_LINE;
side = FOCUS_SIDE;
ne = FOCUS_NE;
nw = FOCUS_NW;
se = FOCUS_SE;
sw = FOCUS_SW;
}
else {
lin = LINE;
side = SIDE;
ne = NE;
nw = NW;
se = SE;
sw = SW;
}
line[WindowWidth(wnd)] = '\0';
/* ---------- window title ------------ */
if (TestAttribute(wnd, TITLEBAR))
if (RectTop(rc) == 0)
if (RectLeft(rc) < WindowWidth(wnd)-BorderAdj(wnd))
DisplayTitle(wnd, &rc);
foreground = FrameForeground(wnd);
background = FrameBackground(wnd);
/* -------- top frame corners --------- */
if (RectTop(rc) == 0) {
if (RectLeft(rc) == 0)
PutWindowChar(wnd, 0, 0, nw);
if (RectLeft(rc) < WindowWidth(wnd)) {
if (RectRight(rc) >= WindowWidth(wnd)-1)
PutWindowChar(wnd, WindowWidth(wnd)-1, 0, ne);
TopLine(wnd, lin, rc);
}
}
/* ----------- window body ------------ */
for (y = RectTop(rc); y <= RectBottom(rc); y++) {
int ch;
if (y == 0 || y >= WindowHeight(wnd)-1)
continue;
if (RectLeft(rc) == 0)
PutWindowChar(wnd, 0, y, side);
if (RectLeft(rc) < WindowWidth(wnd) &&
RectRight(rc) >= WindowWidth(wnd)-1) {
#ifdef INCLUDE_SCROLLBARS
if (TestAttribute(wnd, VSCROLLBAR))
ch = ( y == 1 ? UPSCROLLBOX :
y == WindowHeight(wnd)-2 ?
DOWNSCROLLBOX :
y-1 == wnd->VScrollBox ?
SCROLLBOXCHAR :
SCROLLBARCHAR );
else
#endif
ch = side;
PutWindowChar(wnd, WindowWidth(wnd)-1, y, ch);
}
#ifdef INCLUDE_SHADOWS
if (RectRight(rc) == WindowWidth(wnd))
shadow_char(wnd, y);
#endif
}
if (RectTop(rc) <= WindowHeight(wnd)-1 &&
RectBottom(rc) >= WindowHeight(wnd)-1) {
/* -------- bottom frame corners ---------- */
if (RectLeft(rc) == 0)
PutWindowChar(wnd, 0, WindowHeight(wnd)-1, sw);
if (RectLeft(rc) < WindowWidth(wnd) &&
RectRight(rc) >= WindowWidth(wnd)-1)
PutWindowChar(wnd, WindowWidth(wnd)-1,
WindowHeight(wnd)-1, se);
/* ----------- bottom line ------------- */
memset(line,lin,WindowWidth(wnd)-1);
#ifdef INCLUDE_SCROLLBARS
if (TestAttribute(wnd, HSCROLLBAR)) {
line[0] = LEFTSCROLLBOX;
line[WindowWidth(wnd)-3] = RIGHTSCROLLBOX;
memset(line+1, SCROLLBARCHAR, WindowWidth(wnd)-4);
line[wnd->HScrollBox] = SCROLLBOXCHAR;
}
#endif
line[WindowWidth(wnd)-2] = line[RectRight(rc)] = '\0';
if (RectLeft(rc) != RectRight(rc) ||
(RectLeft(rc) && RectLeft(rc) < WindowWidth(wnd)-1))
writeline(wnd,
line+(RectLeft(clrc)),
RectLeft(clrc)+1,
WindowHeight(wnd)-1,
FALSE);
#ifdef INCLUDE_SHADOWS
if (RectRight(rc) == WindowWidth(wnd))
shadow_char(wnd, WindowHeight(wnd)-1);
#endif
}
#ifdef INCLUDE_SHADOWS
if (RectBottom(rc) == WindowHeight(wnd))
/* ---------- bottom shadow ------------- */
shadowline(wnd, rc);
#endif
}
static void TopLine(WINDOW wnd, int lin, RECT rc)
{
if (TestAttribute(wnd, TITLEBAR | HASMENUBAR))
return;
if (RectLeft(rc) < RectRight(rc)) {
/* ----------- top line ------------- */
memset(line,lin,WindowWidth(wnd)-1);
line[RectRight(rc)] = '\0';
writeline(wnd, line+RectLeft(rc),
RectLeft(rc)+1, 0, FALSE);
}
}
/* ------ clear the data space of a window -------- */
void ClearWindow(WINDOW wnd, RECT *rcc, int clrchar)
{
if (isVisible(wnd)) {
int y;
RECT rc;
if (rcc == NULL)
rc = RelativeWindowRect(wnd, WindowRect(wnd));
else
rc = *rcc;
if (RectLeft(rc) == 0)
RectLeft(rc) = BorderAdj(wnd);
if (RectRight(rc) > WindowWidth(wnd)-1)
RectRight(rc) = WindowWidth(wnd)-1;
SetStandardColor(wnd);
memset(line, clrchar, sizeof line);
line[RectRight(rc)+1] = '\0';
for (y = RectTop(rc); y <= RectBottom(rc); y++) {
if (y < TopBorderAdj(wnd) ||
y >= WindowHeight(wnd)-1)
continue;
writeline(wnd,
line+(RectLeft(rc)),
RectLeft(rc),
y,
FALSE);
}
}
}
/* -- adjust a window's rectangle to clip it to its parent -- */
static RECT near ClipRect(WINDOW wnd)
{
RECT rc;
rc = wnd->rc;
#ifdef INCLUDE_SHADOWS
if (TestAttribute(wnd, SHADOW)) {
RectBottom(rc)++;
RectRight(rc)++;
}
#endif
if (!TestAttribute(wnd, NOCLIP)) {
WINDOW pwnd = GetParent(wnd);
if (pwnd != NULLWND) {
RectTop(rc) = max(RectTop(rc),
GetClientTop(pwnd));
RectLeft(rc) = max(RectLeft(rc),
GetClientLeft(pwnd));
RectRight(rc) = min(RectRight(rc),
GetClientRight(pwnd));
RectBottom(rc) = min(RectBottom(rc),
GetClientBottom(pwnd));
}
}
RectRight(rc) = min(RectRight(rc), SCREENWIDTH-1);
RectBottom(rc) = min(RectBottom(rc), SCREENHEIGHT-1);
RectLeft(rc) = min(RectLeft(rc), SCREENWIDTH-1);
RectTop(rc) = min(RectTop(rc), SCREENHEIGHT-1);
return rc;
}
/* -- get the video memory that is to be used by a window -- */
void GetVideoBuffer(WINDOW wnd)
{
RECT rc;
int ht;
int wd;
rc = ClipRect(wnd);
ht = RectBottom(rc) - RectTop(rc) + 1;
wd = RectRight(rc) - RectLeft(rc) + 1;
wnd->videosave = realloc(wnd->videosave, (ht * wd * 2));
get_videomode();
if (wnd->videosave != NULL)
getvideo(rc, wnd->videosave);
}
/* --- restore the video memory that was used by a window -- */
void RestoreVideoBuffer(WINDOW wnd)
{
if (wnd->videosave != NULL) {
RECT rc;
rc = ClipRect(wnd);
storevideo(rc, wnd->videosave);
free(wnd->videosave);
wnd->videosave = NULL;
}
}
/* ------ compute the logical line length of a window ------ */
int LineLength(char *ln)
{
int len = strlen(ln);
char *cp = ln;
while ((cp = strchr(cp, CHANGECOLOR)) != NULL) {
cp++;
len -= 3;
}
cp = ln;
while ((cp = strchr(cp, RESETCOLOR)) != NULL) {
cp++;
--len;
}
return len;
}