home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
OS/2 Shareware BBS: 10 Tools
/
10-Tools.zip
/
tvos200.zip
/
TVISION
/
TVOS2.CPP
< prev
next >
Wrap
C/C++ Source or Header
|
1995-04-25
|
13KB
|
362 lines
/*
* tvos2.cpp: Turbo Vision OS/2 functions
* =======================================
* (C)1995 by F.Jalvingh; All rights reserved.
*
* This module contains C++ versions of original assembler code.
*
* $Header$
*
* $Log$
*/
#ifdef __OS2__
#define INCL_OS2
#define INCL_BASE
#define INCL_SUB
#define INCL_DOSFILEMGR
#define INCL_DOSMISC
#define Uses_TView
#define Uses_TGroup
#define Uses_TFrame
#define Uses_TDrawBuffer
#define Uses_THardwareInfo
#define Uses_TKeys
#define Uses_TEventQueue
#define Uses_TScreen
#define Uses_TTerminal
#include <tvision/tv.h>
#include <string.h>
/*
* resetCursor() displays the current cursor IF NEEDED in the view spec'd.
*/
void TView::resetCursor()
{
TView *v, *target;
TGroup *o;
short x, y; // Current cursor position.
x = cursor.x;
y = cursor.y;
target = this;
if( ((sfVisible|sfCursorVis|sfFocused) & state) == (sfVisible|sfCursorVis|sfFocused))
{
/*
* Loop 1: From the current view, then to it's OWNER until the topmost
* owner is reached.. (for o = v; o != NULL; o = o->owner)
*/
for(;;)
{
/*
* View IS the visible active focused view && has a cursor ON. Is
* the cursor within this-view's bounds?
*/
if(x < 0 || y < 0 || x >= target->size.x || y >= target->size.y)
break; // Exit: cursor is off bounds.
x += target->origin.x;
y += target->origin.y; // Make pos within owner.
o = target->owner; // Get owner,
if(o == NULL) // No more owners?
{
/*
* Cursor is VISIBLE!! Set cursor type depending on the INS
* mode: if T, make a BLOCK cursor, else use the original
* cursor from TScreen::cursorLines..
*/
if(state & sfCursorIns) // Insert-mode cursor?
THardwareInfo::setCaretSize(0x0700);
else
THardwareInfo::setCaretSize(TScreen::cursorLines);
THardwareInfo::setCaretPosition(x, y);
return; // Done!!!
}
/**** Handle all views in the current GROUP ****/
v = o->last; // Get 1st view in GROUP,
for(;;)
{
v = v->next; // Move to next (1st) view
if(v == target) break; // Exit if all done,
if(sfVisible & v->state) // Is view visible?
{
/**** If the cursor is obscured by this view disable it, ****/
if(x >= v->origin.x && x < v->origin.x+v->size.x &&
y >= v->origin.y && y < v->origin.y+v->size.y)
goto nocursor;
}
}
/*
* Cursor is NOT obscured by one of this-group's views.. Move to
* the OWNER...
*/
target = (TView *)o; // Make target the owner,
}
}
/**** The cursor is OFF!! ****/
nocursor:
THardwareInfo::setCaretSize(0); // Hide cursor.
}
/****************************************************************************/
/* */
/* CODING: writeView() is the main view writing agent. */
/* */
/****************************************************************************/
static void wvGroup(ushort *buf, short off, TView *target, short bx, short ex, short y);
/*
* wvViews() checks which parts of the region passed are obscured
* by TViews within the master group. Each part is checked to see if it
* reaches the screen. If so, the owner for this group is asked to display
* the area.
*
* It works as follows: each view, starting at <first>, is checked against the
* area. If the area is obscured by ANY view, then it's obscured and we
* return immediately (nothing is visible).
* If the area is NOT obscured the next view is checked for intersection with
* the area. This continues till the <target> view is reached: views after
* the target view have a lower Zorder and are obscured by the target.
*
* If the area is partially obscured each part is checked independently.
*/
static void wvViews(ushort *buf, short off, TView *v, TView *target, short bx, short ex, short y)
{
TGroup *o = target->owner;
short vex, vbx;
ushort *p;
for(;;)
{
v = v->next; // Move to NEXT view (is 1st view 1st time),
if(v == target) // Last one reached?
break;
/**** Check: does the current view intersect with the display item?? ****/
if(v->state & sfVisible) // If visible,
{
if(y >= v->origin.y && y < v->origin.y + v->size.y) // In Y region?
{
/*
* Y coordinates fit: this view's Y falls within the owner's Y.
* Now check if the X coordinates fall within the view..
*/
vex = (vbx = v->origin.x) + v->size.x;
if(bx >= vbx && ex <= vex) return; // Completely obscured -> not exposed!
/*
* Does the current item intersect the current view? If not,
* there's nothing obscured...
*/
if(ex >= vbx && bx < vex) // Overlaps current view?
{
/**** Something is visible here. Check both sides, ****/
if(bx < vbx) // Something visible at LHS?
{
/**** LHS is exposed. Is the RHS exposed too? ****/
if(ex > vex) // RHS also visible.
{
/*
* Auch! Check the RHS recursively!!!!
*/
wvViews(buf, off, v, target, vex, ex, y);
}
/**** The RHS was obscured somewhere. Make the LHS current. ****/
ex = vbx;
}
else if(ex > vex) // Something visible at RHS?
{
/*
* Already certain that this is the ONLY part: the other
* part is obscured. So just continue to check this part.
*/
bx = vex; // Check area AFTER this view.
}
}
}
}
}
/*
* The current part IS visible: display it in the group's buffer, the
* screen oid. Then ask the OWNER of this to display the data.
*/
p = buf + bx - off;
if(o->options & ofPhysical) // This is the SCREEN group?
{
/**** Display whatever's left! ****/
THardwareInfo::cursorOff();
VioWrtCellStr((PCH) p, (ex-bx) * 2, y, bx, 0);
THardwareInfo::cursorOn();
return;
}
else if(o->buffer != 0) // Owner has BUFFER associated?
{
/**** Move to View's buffer, ****/
ushort *d = (ushort *) o->buffer;
d += y * o->size.x + bx;
memcpy(d, p, (ex-bx)*2);
}
if(! o->lockFlag) // Not locked for redraw?
{
/**** Check whatever's left of the line in the OWNER'S owner.. ****/
wvGroup(buf, off, o, bx, ex, y); // Ask OWNER to display area,
return;
}
}
/*
* wvGroup() checks if the part of the line (bx to ex) is exposed on
* the group.
*
* To check, it starts to clip the part according to the part's owner TGroup,
* then it traverses the owner's TView list. For each TView it checks to see
* if that view obscures part(s) of the line. If part of the line is NOT
* obscured that part is checked: a check is made if it's obscured
*/
static void wvGroup(ushort *buf, short off, TView *target, short bx, short ex, short y)
{
TGroup *o;
if( (o = target->owner) == NULL) return; // No owner-> exit.
/**** Make view's position within owner, ****/
y += target->origin.y;
bx += target->origin.x;
ex += target->origin.x;
off += target->origin.x;
/**** Clip view area according to it's owner specification.. ****/
if(y < o->clip.a.y || y >= o->clip.b.y) return; // Not exposed (y out of Group)
if(bx < o->clip.a.x) bx = o->clip.a.x; // Move x to start of region,
if(ex > o->clip.b.x) ex = o->clip.b.x; // And idem for end,
if(bx >= ex) return; // Exit if x clipped out,
/*
* Ok, the part (bx-ex, y) is within the owner's clipping region. Now
* check the children: for each child view of this group that's ABOVE
* the <current> view check if it obscures part of the current line
* part...
*/
wvViews(buf, off, o->last, target, bx, ex, y);
}
/*
* TView::writeView() writes a line buffer to a view, taking care of the
* clipping regions e.a. of the owner view. This function does the actual
* screen write. It's hideously complex so take care when modifying it.
*/
void TView::writeView(short x, short y, short count, ushort *buf)
{
short ex;
/**** 1. Check positions with regard to the view's boundaries ****/
if(y < 0 || y >= size.y) return; // Out of Y boundaries.
if(x < 0) x = 0; // Make sure X starts within view
ex = x + count; // End x position + 1!!
if(ex >= size.x) ex = size.x; // Truncate size to end,
if(x >= ex) return; // Exit if nothing to print,
wvGroup(buf, x, this, x, ex, y);
}
/****************************************************************************/
/* */
/* CODING: TView main writing entrypoints, using writeView().. */
/* */
/****************************************************************************/
/*
* writeLine() writes the specified buffer to the line at (x,y). Only <w>
* chars are written. The buffer's contents is repeated for <h> lines.
*/
void TView::writeLine( short x, short y, short w, short h, const void *b)
{
/**** Repeat the display of <b> from line <y>, <h> times.. ****/
while(h-- > 0)
{
writeView(x, y, w, (ushort *)b); // Write these.
y++;
}
}
/*
* writeBuf() writes the specified buffer to the line at (x,y). Only <w>
* chars are written. The next <w> chars are written on the NEXT line, if <h>
* is > 1.
*/
void TView::writeBuf( short x, short y, short w, short h, const void *b)
{
ushort *p = (ushort *) b;
/**** Repeat the display of <b> from line <y>, <h> times.. ****/
while(h-- > 0)
{
writeView(x, y, w, p); // Write these.
y++;
p += w;
}
}
/*
* writeChar() writes the char in c to the screen N times.
*/
void TView::writeChar( short x, short y, char c, uchar color, short count )
{
ushort buf[256], *p, v, ct;
if(count <= 0) return;
if(count > 256) count = 256;
ct = count;
v = mapColor(color); // Get color to write in,
v = (v << 8) | (ushort)(uchar)c; // Make actual charcode,
p = buf;
while(ct-- > 0)
*p++ = v;
writeView(x, y, count, buf);
}
/*
* writeStr()
*/
void TView::writeStr(short x, short y, const char *str, uchar color)
{
ushort len, buf[256], *p, v, ct;
len = strlen(str); // Get #chars in string,
if(len == 0) return;
if(len > 256) len = 256; // Truncit,
v = mapColor(color); // Get color mapping
v <<= 8; // Shift to attr position,
p = buf;
ct = len;
while(ct-- > 0)
*p++ = v | (ushort) (uchar)*str++;
writeView(x, y, len, buf);
}
#endif