📄 srvfunc.c
字号:
/*
* If this was the current cursor, then draw the new one.
*/
if (cp == curcursor || curcursor == NULL) {
GdMoveCursor(cursorx - cp->cursor.hotx,
cursory - cp->cursor.hoty);
GdSetCursor(&cp->cursor);
}
GsCheckCursor();
}
/*
* Move the cursor to the specified absolute screen coordinates.
* The coordinates are that of the defined hot spot of the cursor.
* The cursor's appearance is changed to that defined for the window
* in which the cursor is moved to. In addition, mouse enter, mouse
* exit, focus in, and focus out events are generated if necessary.
* The current mouse location is also changed.
*/
void
GrMoveCursor(GR_COORD x, GR_COORD y)
{
/*
* Move the cursor only if necessary, offsetting it to
* place the hot spot at the specified coordinates.
*/
if ((x != cursorx) || (y != cursory)) {
if(curcursor) {
GdMoveCursor(x - curcursor->cursor.hotx,
y - curcursor->cursor.hoty);
GdMoveMouse(x, y);
}
cursorx = x;
cursory = y;
}
/*
* Now check to see which window the mouse is in, whether or
* not the cursor shape should be changed, and whether or not
* the input focus window should be changed.
*/
GsCheckMouseWindow();
GsCheckFocusWindow();
GsCheckCursor();
}
/*
* Set the foreground color in a graphics context.
*/
void
GrSetGCForeground(GR_GC_ID gc, GR_COLOR foreground)
{
GR_GC *gcp; /* graphics context */
gcp = GsFindGC(gc);
if (!gcp || gcp->foreground == foreground)
return;
gcp->foreground = foreground;
gcp->changed = GR_TRUE;
}
/*
* Set the background color in a graphics context.
*/
void
GrSetGCBackground(GR_GC_ID gc, GR_COLOR background)
{
GR_GC *gcp; /* graphics context */
gcp = GsFindGC(gc);
if (!gcp || gcp->background == background)
return;
gcp->background = background;
gcp->changed = GR_TRUE;
}
/*
* Set whether or not the background color is drawn in bitmaps and text.
*/
void
GrSetGCUseBackground(GR_GC_ID gc, GR_BOOL flag)
{
GR_GC *gcp; /* graphics context */
flag = (flag != 0);
gcp = GsFindGC(gc);
if (!gcp || gcp->usebackground == flag)
return;
gcp->usebackground = flag;
gcp->changed = GR_TRUE;
}
/*
* Set the drawing mode in a graphics context.
*/
void
GrSetGCMode(GR_GC_ID gc, int mode)
{
GR_GC *gcp; /* graphics context */
gcp = GsFindGC(gc);
if (!gcp || gcp->mode == mode)
return;
if ((mode & GR_MODE_DRAWMASK) > GR_MAX_MODE) {
GsError(GR_ERROR_BAD_DRAWING_MODE, gc);
return;
}
gcp->mode = mode;
gcp->changed = GR_TRUE;
}
/*
* Set the text font in a graphics context.
*/
void
GrSetGCFont(GR_GC_ID gc, GR_FONT_ID font)
{
GR_GC *gcp; /* graphics context */
GR_FONT *fontp;
gcp = GsFindGC(gc);
if (!gcp || gcp->fontid == font)
return;
fontp = GsFindFont(font);
gcp->fontid = font;
gcp->changed = GR_TRUE;
}
/*
* Draw a line in the specified drawable using the specified graphics context.
*/
void
GrLine(GR_DRAW_ID id, GR_GC_ID gc, GR_COORD x1, GR_COORD y1, GR_COORD x2,
GR_COORD y2)
{
GR_DRAWABLE *dp;
switch (GsPrepareDrawing(id, gc, &dp)) {
case GR_DRAW_TYPE_WINDOW:
case GR_DRAW_TYPE_PIXMAP:
GdLine(dp->psd, dp->x + x1, dp->y + y1,
dp->x + x2, dp->y + y2, TRUE);
break;
}
}
/*
* Draw the boundary of a rectangle in the specified drawable using the
* specified graphics context.
* NOTE: this function draws a rectangle 1 pixel wider and higher
* than Xlib's XDrawRectangle().
*/
void
GrRect(GR_DRAW_ID id, GR_GC_ID gc, GR_COORD x, GR_COORD y, GR_SIZE width,
GR_SIZE height)
{
GR_DRAWABLE *dp;
switch (GsPrepareDrawing(id, gc, &dp)) {
case GR_DRAW_TYPE_WINDOW:
case GR_DRAW_TYPE_PIXMAP:
GdRect(dp->psd, dp->x + x, dp->y + y, width, height);
break;
}
}
/*
* Fill a rectangle in the specified drawable using the specified
* graphics context.
*/
void
GrFillRect(GR_DRAW_ID id, GR_GC_ID gc, GR_COORD x, GR_COORD y,
GR_SIZE width, GR_SIZE height)
{
GR_DRAWABLE *dp;
switch (GsPrepareDrawing(id, gc, &dp)) {
case GR_DRAW_TYPE_WINDOW:
case GR_DRAW_TYPE_PIXMAP:
GdFillRect(dp->psd, dp->x + x, dp->y + y, width,height);
break;
}
}
/*
* Draw the boundary of an ellipse in the specified drawable with
* the specified graphics context. Integer only.
*/
void
GrEllipse(GR_DRAW_ID id, GR_GC_ID gc, GR_COORD x, GR_COORD y, GR_SIZE rx,
GR_SIZE ry)
{
GR_DRAWABLE *dp;
switch (GsPrepareDrawing(id, gc, &dp)) {
case GR_DRAW_TYPE_WINDOW:
case GR_DRAW_TYPE_PIXMAP:
GdEllipse(dp->psd, dp->x + x, dp->y + y, rx, ry, FALSE);
break;
}
}
/*
* Fill an ellipse in the specified drawable using the specified
* graphics context. Integer only.
*/
void
GrFillEllipse(GR_DRAW_ID id, GR_GC_ID gc, GR_COORD x, GR_COORD y, GR_SIZE rx,
GR_SIZE ry)
{
GR_DRAWABLE *dp;
switch (GsPrepareDrawing(id, gc, &dp)) {
case GR_DRAW_TYPE_WINDOW:
case GR_DRAW_TYPE_PIXMAP:
GdEllipse(dp->psd, dp->x + x, dp->y + y, rx, ry, TRUE);
break;
}
}
/*
* Draw an arc, pie or ellipse in the specified drawable using
* the specified graphics context. Integer only.
*/
void
GrArc(GR_DRAW_ID id, GR_GC_ID gc, GR_COORD x, GR_COORD y,
GR_SIZE rx, GR_SIZE ry, GR_COORD ax, GR_COORD ay,
GR_COORD bx, GR_COORD by, int type)
{
GR_DRAWABLE *dp;
switch (GsPrepareDrawing(id, gc, &dp)) {
case GR_DRAW_TYPE_WINDOW:
case GR_DRAW_TYPE_PIXMAP:
GdArc(dp->psd, dp->x + x, dp->y + y, rx, ry,
dp->x+ax, dp->y+ay, dp->x+bx, dp->y+by, type);
break;
}
}
/*
* Draw an arc or pie in the specified drawable using
* the specified graphics context. Requires floating point.
*/
void
GrArcAngle(GR_DRAW_ID id, GR_GC_ID gc, GR_COORD x, GR_COORD y,
GR_SIZE rx, GR_SIZE ry, GR_COORD angle1, GR_COORD angle2, int type)
{
GR_DRAWABLE *dp;
switch (GsPrepareDrawing(id, gc, &dp)) {
case GR_DRAW_TYPE_WINDOW:
case GR_DRAW_TYPE_PIXMAP:
GdArcAngle(dp->psd, dp->x + x, dp->y + y, rx, ry,
angle1, angle2, type);
break;
}
}
/*
* Draw a rectangular area in the specified drawable using the specified
* graphics, as determined by the specified bit map. This differs from
* rectangle drawing in that the rectangle is drawn using the foreground
* color and possibly the background color as determined by the bit map.
* Each row of bits is aligned to the next bitmap word boundary (so there
* is padding at the end of the row). The background bit values are only
* written if the usebackground flag is set in the GC.
*/
void
GrBitmap(GR_DRAW_ID id, GR_GC_ID gc, GR_COORD x, GR_COORD y, GR_SIZE width,
GR_SIZE height, GR_BITMAP *imagebits)
{
GR_DRAWABLE *dp;
switch (GsPrepareDrawing(id, gc, &dp)) {
case GR_DRAW_TYPE_WINDOW:
case GR_DRAW_TYPE_PIXMAP:
GdBitmap(dp->psd, dp->x + x, dp->y + y, width, height,
imagebits);
break;
}
}
/* draw a multicolor image at x, y*/
void
GrDrawImageBits(GR_DRAW_ID id, GR_GC_ID gc, GR_COORD x, GR_COORD y,
GR_IMAGE_HDR *pimage)
{
GR_DRAWABLE *dp;
switch (GsPrepareDrawing(id, gc, &dp)) {
case GR_DRAW_TYPE_WINDOW:
case GR_DRAW_TYPE_PIXMAP:
GdDrawImage(dp->psd, dp->x + x, dp->y + y, pimage);
break;
}
}
#if !((DOS_DJGPP) || (__PACIFIC__) || (DOS_TURBOC))
/* Load an image file from disk and display it at the specified coordinates*/
void
GrDrawImageFromFile(GR_DRAW_ID id, GR_GC_ID gc, GR_COORD x, GR_COORD y,
GR_SIZE width, GR_SIZE height, char* path, int flags)
{
#if defined(HAVE_FILEIO)
GR_DRAWABLE *dp;
switch (GsPrepareDrawing(id, gc, &dp)) {
case GR_DRAW_TYPE_WINDOW:
case GR_DRAW_TYPE_PIXMAP:
GdDrawImageFromFile(dp->psd, dp->x + x, dp->y + y,
width, height, path, flags);
break;
}
#endif
}
/* load image from file and cache it*/
GR_IMAGE_ID
GrLoadImageFromFile(char *path, int flags)
{
#if defined(HAVE_FILEIO)
GR_IMAGE_ID id;
GR_IMAGE * imagep;
id = GdLoadImageFromFile(&scrdev, path, flags);
if (!id)
return 0;
imagep = (GR_IMAGE *) malloc(sizeof(GR_IMAGE));
if (imagep == NULL) {
GsError(GR_ERROR_MALLOC_FAILED, 0);
GdFreeImage(id);
return 0;
}
imagep->id = id;
imagep->owner = curclient;
imagep->next = listimagep;
listimagep = imagep;
return id;
#else
return 0;
#endif
}
/* Draw an image from a buffer */
void
GrDrawImageFromBuffer(GR_DRAW_ID id, GR_GC_ID gc, GR_COORD x, GR_COORD y,
GR_SIZE width, GR_SIZE height,
void *buffer, int size, int flags)
{
GR_DRAWABLE *dp;
switch (GsPrepareDrawing(id, gc, &dp)) {
case GR_DRAW_TYPE_WINDOW:
case GR_DRAW_TYPE_PIXMAP:
GdDrawImageFromBuffer(dp->psd, dp->x + x, dp->y + y,
width, height, buffer, size, flags);
break;
}
}
/* load image from the given buffer and cache it*/
GR_IMAGE_ID
GrLoadImageFromBuffer(void *buffer, int size, int flags)
{
GR_IMAGE_ID id;
GR_IMAGE * imagep;
id = GdLoadImageFromBuffer(&scrdev, buffer, size, flags);
if (!id) return(0);
imagep = (GR_IMAGE *) malloc(sizeof(GR_IMAGE));
if (imagep == NULL) {
GsError(GR_ERROR_MALLOC_FAILED, 0);
GdFreeImage(id);
return 0;
}
imagep->id = id;
imagep->owner = curclient;
imagep->next = listimagep;
listimagep = imagep;
return id;
}
/* draw cached image*/
void
GrDrawImageToFit(GR_DRAW_ID id, GR_GC_ID gc, GR_COORD x, GR_COORD y,
GR_SIZE width, GR_SIZE height, GR_IMAGE_ID imageid)
{
#if defined(HAVE_FILEIO)
GR_DRAWABLE *dp;
switch (GsPrepareDrawing(id, gc, &dp)) {
case GR_DRAW_TYPE_WINDOW:
case GR_DRAW_TYPE_PIXMAP:
GdDrawImageToFit(dp->psd, dp->x + x, dp->y + y,
width, height, imageid);
break;
}
#endif
}
/* free cached image*/
void
GrFreeImage(GR_IMAGE_ID id)
{
#if defined(HAVE_FILEIO)
GR_IMAGE *imagep;
GR_IMAGE *previmagep;
for (imagep = listimagep; imagep; imagep = imagep->next) {
if (imagep->id == id) {
if (listimagep == imagep)
listimagep = imagep->next;
else {
previmagep = listimagep;
while (previmagep->next != imagep)
previmagep = previmagep->next;
previmagep->next = imagep->next;
}
GdFreeImage(imagep->id);
free(imagep);
return;
}
}
#endif
}
/* return cached image information*/
void
GrGetImageInfo(GR_IMAGE_ID id, GR_IMAGE_INFO *iip)
{
#if defined(HAVE_FILEIO)
GdGetImageInfo(id, iip);
#else
memset(iip, 0, sizeof(GR_IMAGE_INFO));
#endif
}
#endif /* !defined (DOS_DJGPP)|| (__PACIFIC__) || (DOS_TURBOC)) */
/*
* Draw a rectangular area in the specified drawable using the specified
* graphics context. This differs from rectangle drawing in that the
* color values for each pixel in the rectangle are specified.
* The color table is indexed row by row.
*/
void
GrArea(GR_DRAW_ID id, GR_GC_ID gc, GR_COORD x, GR_COORD y, GR_SIZE width,
GR_SIZE height, void *pixels, int pixtype)
{
GR_DRAWABLE *dp;
switch (GsPrepareDrawing(id, gc, &dp)) {
case GR_DRAW_TYPE_WINDOW:
case GR_DRAW_TYPE_PIXMAP:
GdArea(dp->psd, dp->x + x, dp->y + y, width, height,
pixels, pixtype);
break;
}
}
/*
* Copy a rectangle from one drawable to another or the same
*/
void
GrCopyArea(GR_DRAW_ID id, GR_GC_ID gc, GR_COORD x, GR_COORD y,
GR_SIZE width, GR_SIZE height, GR_DRAW_ID source,
GR_COORD srcx, GR_COORD srcy, int op)
{
GR_DRAWABLE *dp;
GR_WINDOW *swp;
GR_PIXMAP *spp = NULL;
GR_DRAW_TYPE type;
PSD srcpsd;
srcpsd = NULL;
swp = GsFindWindow(source);
type = GsPrepareDrawing(id, gc, &dp);
if (type == GR_DRAW_TYPE_NONE)
return;
if (swp) {
srcpsd = swp->psd;
srcx += swp->x;
srcy += swp->y;
} else {
spp = GsFindPixmap(source);
if (spp)
srcpsd = spp->psd;
}
if (!srcpsd)
return;
#if DYNAMICREGIONS
/*
* Skip blit and send expose event if window is partly
* obscured and source and destination are onscreen.
* Also check that receiving window's first client has
* selected for expose events. This keeps brain-dead
* programs that don't process exposure events somewhat working.
*/
if (swp && (srcpsd == dp->psd) && swp->eventclients &&
(swp->eventclients->eventmask & GR_EVENT_MASK_EXPOSURE)) {
MWRECT rc;
extern MWCLIPREGION *clipregion;
/* clip blit rectangle to source screen/bitmap size*/
if(srcx+width > srcpsd->xvirtres)
width = srcpsd->xvirtres - srcx;
if(srcy+height > srcpsd->yvirtres)
height = srcpsd->yvirtres - srcy;
rc.left = srcx;
rc.top = srcy;
rc.right = srcx + width;
rc.bottom = srcy + height;
/*
* if source isn't entirely within clip region, then
* the blit is partly obscured and will copy some garbage.
* In this case, skip the blit, punt, and deliver an
* exposure event instead for proper display.
*/
if (GdRectInRegion(clipregion, &rc) != MWRECT_ALLIN) {
GsDeliverExposureEvent(swp, dp->x+x, dp->y+y,
width, height);
return;
}
}
#endif
/* perform blit*/
GdCheckCursor(srcpsd, srcx, srcy, srcx+width, srcy+height); /* FIXME*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -