home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
PC Shareware 1999 March
/
PCShareware-3-99.iso
/
IMPLE
/
DJGPP.RAR
/
DJGPP2
/
XLIB-SR0.ZIP
/
SRC
/
XLIBEMU
/
INTERNAL.C
< prev
next >
Wrap
C/C++ Source or Header
|
1994-02-20
|
13KB
|
590 lines
/* $Id: internal.c 1.4 1994/02/20 19:49:38 ulrich Exp $ */
/*
* internal.c
*
* Internal window handling functions for Xlibemu.
*/
#include "Xlibemu.h"
#include <stdio.h>
extern GrContext _WScreenContext;
void
_WDummyFilledBox ()
{
}
void
_WContextFilledBox (int x1, int y1, int x2, int y2, GrContext *src)
{
int x, y, width, height;
width = src->gc_xmax + 1;
height = src->gc_ymax + 1;
for (y = y1; y < y2; y += height)
{
for (x = x1; x < x2; x += width)
{
GrBitBlt (NULL, x, y, src, 0, 0, width-1, height-1, GrWRITE);
}
}
}
Window
_WMaskEventWindow (Window w, unsigned long mask)
{
while (w)
{
if (w->event_mask & mask)
return w;
if (w->do_not_propagate_mask & mask)
return None;
w = w->parent;
}
return None;
}
int
_WRectIntersect (BoxPtr r1, BoxPtr r2, BoxPtr rr)
{
rr->x1 = MAX(r1->x1, r2->x1);
rr->y1 = MAX(r1->y1, r2->y1);
rr->x2 = MIN(r1->x2, r2->x2);
rr->y2 = MIN(r1->y2, r2->y2);
return (rr->x1 >= rr->x2 || rr->y1 >= rr->y2) ? False : True;
}
/*
* Return the x and y screen coordinates of the top-left pixel
* just inside the window's border.
*/
void
_WGetWindowOrigin (Window window, int *x_root, int *y_root)
{
int x, y;
x = 0;
y = 0;
for (; window != None; window = window->parent)
{
x += window->x + window->border_width;
y += window->y + window->border_width;
}
*x_root = x;
*y_root = y;
}
void
_WGetWindowPort (Window window, BoxPtr port)
{
int x1, y1;
_WGetWindowOrigin (window, &x1, &y1);
port->x1 = x1;
port->y1 = y1;
port->x2 = x1 + window->width;
port->y2 = y1 + window->height;
}
void
_WGetBorderPort (Window window, BoxPtr port)
{
int x1, y1;
_WGetWindowOrigin (window, &x1, &y1);
port->x1 = x1 - window->border_width;
port->y1 = y1 - window->border_width;
port->x2 = x1 + window->width + window->border_width;
port->y2 = y1 + window->height + window->border_width;
}
/*
* Clip the window port by all parent window ports.
* Return value:
* 1 if port is not empty
* 0 otherwise.
*/
int
_WClipPortByParents (Window window, BoxPtr port)
{
*port = window->window_port;
while ((window = window->parent) != NULL) {
if (_WRectIntersect (&window->window_port, port, port) == 0)
return 0;
}
return 1;
}
/*
* Clip the window border port by all parent window ports.
* Return value:
* 1 if port is not empty
* 0 otherwise.
*/
int
_WClipBorderByParents (Window window, BoxPtr port)
{
*port = window->border_port;
while ((window = window->parent) != NULL) {
if (_WRectIntersect (&window->window_port, port, port) == 0)
return 0;
}
return 1;
}
Window
_WPointToWindow (Display *dpy, int x, int y)
{
Window window, parent;
window = DefaultRootWindow (dpy);
parent = NULL;
while (window != None) {
if (window->mapped != 0 &&
INBOX(window->window_port, x, y)) {
parent = window;
window = window->top_child;
continue;
}
window = window->lower_sibling;
}
return parent;
}
Window
_WPointToWindowBorder (Display *dpy, int x, int y)
{
Window window, parent;
window = DefaultRootWindow (dpy);
parent = NULL;
while (window != None) {
if (window->mapped != 0 &&
INBOX(window->border_port, x, y)) {
parent = window;
window = window->top_child;
continue;
}
window = window->lower_sibling;
}
return parent;
}
Cursor
_WGetWindowCursor (Window window)
{
while (window != NULL && window->cursor == NULL) {
window = window->parent;
}
return (window == NULL) ? None : window->cursor;
}
void
_WSetViewable (Window parent, Bool viewable)
{
Window window;
for (window = parent->bottom_child;
window != None;
window = window->upper_sibling) {
window->viewable = viewable ? window->mapped : False;
_WSetViewable (window, window->viewable);
}
}
void
_WSetMapping (Window parent, Bool mapped)
{
Window window;
for (window = parent->bottom_child;
window != None;
window = window->upper_sibling) {
window->mapped = mapped;
_WSetMapping (window, mapped);
}
}
/*
* Draw visible parts of windows background and border.
*/
void
_WDrawWindowBorder (Display *dpy, Window w, BoxPtr rect, Bool exposures)
{
BoxRec bp;
int bw;
void (*fillBox)();
long fillArg;
if ((bw = w->border_width) == 0)
return;
if (! _WRectIntersect (rect, &w->border_port, &bp))
return;
fillBox = w->border.fillBox;
fillArg = w->border.fillArg;
_WDrawScreenContext ((Drawable) w);
_WDrawRegion (fillBox, bp.x1, bp.y1, bp.x2-1, bp.y1+bw-1, fillArg);
_WDrawRegion (fillBox, bp.x1, bp.y2-bw, bp.x2-1, bp.y2-1, fillArg);
_WDrawRegion (fillBox, bp.x1, bp.y1+bw, bp.x1+bw-1, bp.y2-1-bw, fillArg);
_WDrawRegion (fillBox, bp.x2-bw, bp.y1+bw, bp.x2-1, bp.y2-1-bw, fillArg);
}
void
_WDrawWindowBackground (Display *dpy, Window w, BoxPtr p, Bool exposures)
{
BoxRec port;
if (! _WRectIntersect (&w->window_port, p, &port))
return;
if (! XRectInRegion (w->visible_region,
port.x1, port.y1,
port.x2 - port.x1, port.y2 - port.y1))
return;
_WDrawScreenContext ((Drawable) w);
_WDrawRegion (w->background.fillBox,
port.x1, port.y1, port.x2 - 1, port.y2 - 1,
w->background.fillArg);
if (exposures == True && w->event_mask & ExposureMask) {
XEvent xe;
xe.xexpose.type = Expose;
xe.xexpose.send_event = 0;
xe.xexpose.display = dpy;
xe.xexpose.window = w;
xe.xexpose.x = port.x1 - w->window_port.x1;
xe.xexpose.y = port.y1 - w->window_port.y1;
xe.xexpose.width = port.x2 - port.x1;
xe.xexpose.height = port.y2 - port.y1;
xe.xexpose.count = 0;
_WDispatchEvent (&xe);
}
}
void
_WDrawWindow (Display* dpy, Window window, BoxPtr rect, Bool exposures)
{
if (window->viewable == 0 || window->class != InputOutput)
return;
_WDrawWindowBorder (dpy, window, rect, exposures);
_WDrawWindowBackground (dpy, window, rect, exposures);
}
void
_WDrawSubwindows (Display *dpy, Window window, BoxPtr rect, Bool exposures)
{
Window child;
for (child = window->bottom_child;
child != None;
child = child->upper_sibling) {
if (! child->viewable) continue;
_WDrawWindow (dpy, child, rect, exposures);
_WDrawSubwindows (dpy, child, rect, exposures);
}
}
/* draw window background region and expose optional */
void
_WDrawWindowBackgroundRegion (Display *dpy, Window w, Region rgn, Bool exposures)
{
int i, x1, y1, x2, y2;
BoxPtr pbox;
_WDrawScreenContext ((Drawable) w);
pbox = rgn->rects;
for (i = rgn->numRects; --i >= 0; pbox++) {
x1 = pbox->x1;
y1 = pbox->y1;
x2 = pbox->x2;
y2 = pbox->y2;
_WDrawRegion (w->background.fillBox, x1, y1, x2 - 1, y2 - 1,
w->background.fillArg);
if (exposures == True && w->event_mask & ExposureMask) {
XEvent xe;
xe.xexpose.type = Expose;
xe.xexpose.send_event = 0;
xe.xexpose.display = dpy;
xe.xexpose.window = w;
xe.xexpose.x = x1 - w->window_port.x1;
xe.xexpose.y = y1 - w->window_port.y1;
xe.xexpose.width = x2 - x1;
xe.xexpose.height = y2 - y1;
xe.xexpose.count = i;
_WDispatchEvent (&xe);
}
}
}
void
_WDrawSiblingsBelow (Display *dpy, Window window, Bool exposures)
{
Window sibling;
for (sibling = window;
sibling = sibling->lower_sibling;) {
#if 0
if (! EXTENTCHECK(&window->border_port, &sibling->border_port))
continue;
#endif
_WDrawWindow (dpy, sibling, &window->border_port, exposures);
_WDrawSubwindows (dpy, sibling, &window->border_port, exposures);
}
}
void
_WSetVisibleSubwindows (Window window)
{
Window child;
for (child = window->bottom_child;
child != None;
child = child->upper_sibling) {
_WSetVisibleRegion (child);
_WSetVisibleSubwindows (child);
}
}
void
_WSetVisibleSubwindowsInBox (Window window, BoxPtr pbox)
{
Window child;
for (child = window->bottom_child;
child != None;
child = child->upper_sibling) {
if (! EXTENTCHECK(pbox, &child->border_port)) continue;
_WSetVisibleRegion (child);
_WSetVisibleSubwindows (child);
}
}
/*
* Window size or position has changed.
* Recreate Graphics context, recompute window and border port.
*/
void
_WNewWindowContext (Window window)
{
Window child;
for (child = window->top_child;
child != NULL;
child = child->lower_sibling) {
_WNewWindowContext (child);
}
_WGetWindowPort (window, &window->window_port);
_WGetBorderPort (window, &window->border_port);
if (window->context)
GrDestroyContext (window->context);
window->context =
GrCreateSubContext (window->window_port.x1,
window->window_port.y1,
window->window_port.x2 - 1,
window->window_port.y2 - 1,
&_WScreenContext, NULL);
}
void
_WUnmapSubwindows (Window parent)
{
Window window;
for (window = parent->top_child;
window != NULL;
window = window->lower_sibling) {
window->mapped = 0;
_WUnmapSubwindows (window);
}
}
void
_WDefineCursor (Cursor new_cursor)
{
if (new_cursor == None || new_cursor == _Cursor) return;
_Cursor = new_cursor;
_WMouseSetCursor (_Cursor);
}
/*
* Recompute the visible region (includes border) of window.
* Set visibility depending on region.
* Region coordinates are screen absolute.
*/
int
_WSetVisibleRegion (Window window)
{
REGION temp;
Region region;
Window child, parent, sibling;
BoxRec port, port1;
region = window->visible_region;
EMPTY_REGION(region);
if (window->viewable == 0)
return 0;
if (! _WClipBorderByParents (window, &port))
goto set_visibility;
temp.rects = &temp.extents;
temp.numRects = 1;
temp.extents = port;
temp.size = 1;
XUnionRegion (region, &temp, region);
for (child = window->top_child;
child != None;
child = child->lower_sibling) {
if (! child->viewable || child->class != InputOutput)
continue;
/*
* Child window may only overlap parent's drawing area
*/
if (! _WRectIntersect (&window->window_port,
&child->border_port,
&port1))
continue;
if (! _WRectIntersect (&port, &port1, &temp.extents))
continue;
/***
if (! EXTENTCHECK(&child->border_port, &port)) continue;
temp.extents = child->border_port;
***/
XSubtractRegion (region, &temp, region);
}
for (parent = window;
parent != None;
parent = parent->parent) {
for (sibling = parent;
sibling = sibling->upper_sibling;) {
if (! sibling->viewable || sibling->class != InputOutput)
continue;
if (! EXTENTCHECK(&sibling->border_port, &port))
continue;
temp.extents = sibling->border_port;
XSubtractRegion (region, &temp, region);
if (region->numRects == 0) goto set_visibility;
}
}
set_visibility:
switch (region->numRects) {
case 0:
window->visibility = VisibilityFullyObscured;
break;
case 1:
window->visibility = VisibilityUnobscured;
break;
default:
window->visibility = VisibilityPartiallyObscured;
break;
}
return REGION_NOT_EMPTY(region);
}
int
_WInvalidateRectangle (Window w, BoxPtr pRect)
{
REGION region;
if (w->visible_region == NULL)
_WSetVisibleRegion (w);
region.rects = ®ion.extents;
region.numRects = 1;
region.extents = *pRect;
region.size = 1;
XSubtractRegion (w->visible_region, ®ion, w->visible_region);
return REGION_NOT_EMPTY(w->visible_region);
}
int
_WInvalidateParent (Window w)
{
BoxRec port;
Window sibling;
if (! _WClipBorderByParents (w, &port))
return 0;
_WInvalidateRectangle (w->parent, &port);
#if 0
for (sibling = w;
sibling = sibling->lower_sibling;) {
if (! EXTENTCHECK(&port, &sibling->border_port)) continue;
_WInvalidateRectangle (sibling, &port);
}
#endif
return 0;
}
/* Convert current rawclock time to milliseconds */
Time _WCurrentTime()
{
extern long rawclock();
return rawclock() * 54.931;
}
/* Convert rawclock time to milliseconds */
Time _WConvertTime(long event_time)
{
return event_time * 54.931;
}
/* Return True if A is an inferior of B */
Bool
_WIsInferior (Window a, Window b)
{
while (b != None) {
if (b->parent == a)
return True;
b = b->parent;
}
return False;
}
/* Return True if W is the focus window or an inferior of
* the focus window */
Bool
_WIsFocus (Window root, Window w)
{
if (_Focus.window == None)
return False;
if (_Focus.window == (Window) PointerRoot) {
if (_WIsInferior (root, w) || w == root)
return True;
}
else {
if (_WIsInferior (_Focus.window, w) || w == _Focus.window)
return True;
}
return False;
}