⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 srvfunc.c

📁 开放源码实时操作系统源码.
💻 C
📖 第 1 页 / 共 5 页
字号:

	/*
	 * 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 + -