📄 srvutil.c
字号:
/*
* Draw a tiled pixmap window background.
*/
void
GsWpTileBackgroundPixmap(GR_WINDOW *wp, GR_PIXMAP *pm, GR_COORD x, GR_COORD y,
GR_SIZE width, GR_SIZE height)
{
GR_COORD tilex = 0, tiley = 0, fromx, fromy, cx, cy;
GR_SIZE destwidth, destheight, pmwidth, pmheight, cwidth, cheight;
if(pm->width > wp->width) pmwidth = wp->width;
else pmwidth = pm->width;
if(pm->height > wp->height) pmheight = wp->height;
else pmheight = pm->height;
for(;tiley < wp->height; tiley += pmheight, tilex = 0) {
if(tiley > (y + height)) continue;
if(y > (tiley + pmheight)) continue;
if((tiley + pmheight) > wp->height)
destheight = wp->height - tiley;
else destheight = pmheight;
for(;tilex < wp->width; tilex += pmwidth) {
if(tilex > (x + width)) continue;
if(x > (tilex + pmwidth)) continue;
if((tilex + pmwidth) > wp->width)
destwidth = wp->width - tilex;
else destwidth = pmwidth;
if((tilex >= x) && ((tilex + destwidth)<=(x + width))) {
fromx = 0;
cx = tilex + wp->x;
cwidth = destwidth;
} else {
if(x > tilex) {
fromx = x - tilex;
cwidth = destwidth - fromx;
} else {
fromx = 0;
cwidth = x + width - tilex;
}
if(cwidth > width) cwidth = width;
if(cwidth > destwidth) cwidth = destwidth;
cx = wp->x + tilex + fromx;
}
if((tiley >= y)&&((tiley + destheight)<=(y + height))) {
fromy = 0;
cy = tiley + wp->y;
cheight = destheight;
} else {
if(y > tiley) {
fromy = y - tiley;
cheight = destheight - fromy;
} else {
fromy = 0;
cheight = y + height - tiley;
}
if(cwidth > width) cwidth = width;
if(cheight > destheight) cheight = destheight;
cy = wp->y + tiley + fromy;
}
if((cwidth > 0) && (cheight > 0)) {
GdBlit(wp->psd, cx, cy, cwidth, cheight,
pm->psd, fromx, fromy, MWROP_COPY);
}
}
}
}
/*
* Clear the specified area of a window and possibly make an exposure event.
* This sets the area window to its background color or pixmap. If the
* exposeflag is nonzero, then this also creates an exposure event for the
* window.
*/
void
GsWpClearWindow(GR_WINDOW *wp, GR_COORD x, GR_COORD y, GR_SIZE width,
GR_SIZE height, GR_BOOL exposeflag)
{
if (wp->unmapcount || !wp->output)
return;
/*
* Reduce the arguments so that they actually lie within the window.
*/
if (x < 0) {
width += x;
x = 0;
}
if (y < 0) {
height += y;
y = 0;
}
if (x + width > wp->width)
width = wp->width - x;
if (y + height > wp->height)
height = wp->height - y;
/*
* Now see if the region is really in the window. If not, then
* do nothing.
*/
if ((x >= wp->width) || (y >= wp->height) || (width <= 0) ||
(height <= 0))
return;
/*
* Draw the background of the window.
* Invalidate the current graphics context since
* we are changing the foreground color and mode.
*/
GsSetClipWindow(wp, NULL, 0);
curgcp = NULL;
if (!(wp->props & GR_WM_PROPS_NOBACKGROUND)) {
GdSetMode(GR_MODE_COPY);
GdSetForeground(GdFindColor(wp->background));
if (wp->bgpixmap) {
GsWpDrawBackgroundPixmap(wp, wp->bgpixmap, x, y,
width, height);
} else {
GdFillRect(wp->psd, wp->x + x, wp->y + y, width,height);
}
}
/*
* Now do the exposure if required.
*/
if (exposeflag)
GsDeliverExposureEvent(wp, x, y, width, height);
}
/*
* Handle the exposing of the specified absolute region of the screen,
* starting with the specified window. That window and all of its
* children will be redrawn and/or exposure events generated if they
* overlap the specified area. This is a recursive routine.
*/
void
GsExposeArea(GR_WINDOW *wp, GR_COORD rootx, GR_COORD rooty, GR_SIZE width,
GR_SIZE height, GR_WINDOW *stopwp)
{
if (!wp->output || wp->unmapcount || wp == stopwp)
return;
/*
* First see if the area overlaps the window including the border.
* If not, then there is nothing more to do.
*/
if ((rootx >= wp->x + wp->width + wp->bordersize) ||
(rooty >= wp->y + wp->height + wp->bordersize) ||
(rootx + width <= wp->x - wp->bordersize) ||
(rooty + height <= wp->y - wp->bordersize))
return;
/*
* The area does overlap the window. See if the area overlaps
* the border, and if so, then redraw it.
*/
if ((rootx < wp->x) || (rooty < wp->y) ||
(rootx + width > wp->x + wp->width) ||
(rooty + height > wp->y + wp->height))
GsDrawBorder(wp);
/*
* Now clear the window itself in the specified area,
* which might cause an exposure event.
*/
GsWpClearWindow(wp, rootx - wp->x, rooty - wp->y,
width, height, GR_TRUE);
/*
* Now do the same for all the children.
*/
for (wp = wp->children; wp; wp = wp->siblings)
GsExposeArea(wp, rootx, rooty, width, height, stopwp);
}
/*
* Draw the border of a window if there is one.
* Note: To allow the border to be drawn with the correct clipping,
* we temporarily grow the size of the window to include the border.
*/
void GsDrawBorder(GR_WINDOW *wp)
{
GR_COORD lminx; /* left edge minimum x */
GR_COORD rminx; /* right edge minimum x */
GR_COORD tminy; /* top edge minimum y */
GR_COORD bminy; /* bottom edge minimum y */
GR_COORD topy; /* top y value of window */
GR_COORD boty; /* bottom y value of window */
GR_SIZE width; /* original width of window */
GR_SIZE height; /* original height of window */
GR_SIZE bs; /* border size */
bs = wp->bordersize;
if (bs <= 0)
return;
width = wp->width;
height = wp->height;
lminx = wp->x - bs;
rminx = wp->x + width;
tminy = wp->y - bs;
bminy = wp->y + height;
topy = wp->y;
boty = bminy - 1;
wp->x -= bs;
wp->y -= bs;
wp->width += (bs * 2);
wp->height += (bs * 2);
wp->bordersize = 0;
clipwp = NULL;
GsSetClipWindow(wp, NULL, 0);
curgcp = NULL;
GdSetMode(GR_MODE_COPY);
GdSetForeground(GdFindColor(wp->bordercolor));
if (bs == 1) {
GdLine(wp->psd, lminx, tminy, rminx, tminy, TRUE);
GdLine(wp->psd, lminx, bminy, rminx, bminy, TRUE);
GdLine(wp->psd, lminx, topy, lminx, boty, TRUE);
GdLine(wp->psd, rminx, topy, rminx, boty, TRUE);
} else {
GdFillRect(wp->psd, lminx, tminy, width + bs * 2, bs);
GdFillRect(wp->psd, lminx, bminy, width + bs * 2, bs);
GdFillRect(wp->psd, lminx, topy, bs, height);
GdFillRect(wp->psd, rminx, topy, bs, height);
}
/*
* Restore the true window size.
* Forget the currently clipped window since we messed it up.
*/
wp->x += bs;
wp->y += bs;
wp->width -= (bs * 2);
wp->height -= (bs * 2);
wp->bordersize = bs;
clipwp = NULL;
}
/*
* Check to see if the first window overlaps the second window.
*/
GR_BOOL GsCheckOverlap(GR_WINDOW *topwp, GR_WINDOW *botwp)
{
GR_COORD minx1;
GR_COORD miny1;
GR_COORD maxx1;
GR_COORD maxy1;
GR_COORD minx2;
GR_COORD miny2;
GR_COORD maxx2;
GR_COORD maxy2;
GR_SIZE bs;
if (!topwp->output || topwp->unmapcount || botwp->unmapcount)
return GR_FALSE;
bs = topwp->bordersize;
minx1 = topwp->x - bs;
miny1 = topwp->y - bs;
maxx1 = topwp->x + topwp->width + bs - 1;
maxy1 = topwp->y + topwp->height + bs - 1;
bs = botwp->bordersize;
minx2 = botwp->x - bs;
miny2 = botwp->y - bs;
maxx2 = botwp->x + botwp->width + bs - 1;
maxy2 = botwp->y + botwp->height + bs - 1;
if ((minx1 > maxx2) || (minx2 > maxx1) || (miny1 > maxy2)
|| (miny2 > maxy1))
return GR_FALSE;
return GR_TRUE;
}
/*
* Return a pointer to the window structure with the specified window id.
* Returns NULL if the window does not exist.
*/
GR_WINDOW *
GsFindWindow(GR_WINDOW_ID id)
{
GR_WINDOW *wp; /* current window pointer */
/*
* See if this is the root window or the same window as last time.
*/
if (id == GR_ROOT_WINDOW_ID)
return rootwp;
if ((id == cachewindowid) && id)
return cachewp;
/*
* No, search for it and cache it for future calls.
*/
for (wp = listwp; wp; wp = wp->next) {
if (wp->id == id) {
cachewindowid = id;
cachewp = wp;
return wp;
}
}
return NULL;
}
/*
* Return a pointer to the pixmap structure with the specified window id.
* Returns NULL if the pixmap does not exist.
*/
GR_PIXMAP *
GsFindPixmap(GR_WINDOW_ID id)
{
GR_PIXMAP *pp; /* current pixmap pointer */
if ((id == cachepixmapid) && id)
return cachepp;
/*
* No, search for it and cache it for future calls.
*/
for (pp = listpp; pp; pp = pp->next) {
if (pp->id == id) {
cachepixmapid = id;
cachepp = pp;
return pp;
}
}
return NULL;
}
/*
* Return a pointer to the graphics context with the specified id.
* Returns NULL if the graphics context does not exist, with an
* error saved.
*/
GR_GC *
GsFindGC(GR_GC_ID gcid)
{
GR_GC *gcp; /* current graphics context pointer */
/*
* See if this is the same graphics context as last time.
*/
if ((gcid == cachegcid) && gcid)
return cachegcp;
/*
* No, search for it and cache it for future calls.
*/
for (gcp = listgcp; gcp; gcp = gcp->next) {
if (gcp->id == gcid) {
cachegcid = gcid;
cachegcp = gcp;
return gcp;
}
}
GsError(GR_ERROR_BAD_GC_ID, gcid);
return NULL;
}
/* Return a pointer to the region with the specified id.*/
GR_REGION *
GsFindRegion(GR_REGION_ID regionid)
{
GR_REGION *regionp; /* current region pointer */
for (regionp = listregionp; regionp; regionp = regionp->next) {
if (regionp->id == regionid) {
return regionp;
}
}
return NULL;
}
/* find a font with specified id*/
GR_FONT *
GsFindFont(GR_FONT_ID fontid)
{
GR_FONT *fontp;
for (fontp = listfontp; fontp; fontp = fontp->next) {
if (fontp->id == fontid)
return fontp;
}
return NULL;
}
/* find a cursor with specified id*/
GR_CURSOR *
GsFindCursor(GR_CURSOR_ID cursorid)
{
GR_CURSOR *cursorp;
for (cursorp = listcursorp; cursorp; cursorp = cursorp->next) {
if (cursorp->id == cursorid)
return cursorp;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -