home *** CD-ROM | disk | FTP | other *** search
- /******************************************************************************
- * Low level graphics routines. *
- * *
- * Written by Gershon Elber, Oct. 1990 *
- *******************************************************************************
- * Supported device: *
- * 1. CGA. *
- * 2. EGA/VGA. *
- * 3. Hercules. *
- * 4. Super VGA. *
- *******************************************************************************
- * History: *
- * 15 Oct 90 - Version 1.0 by Gershon Elber. *
- ******************************************************************************/
-
- #include <string.h>
- #include <stdio.h>
- #include <math.h>
- #include <mem.h>
- #include <dos.h>
- #include <io.h>
- #include <graphics.h>
- #include <conio.h>
- #include <fcntl.h>
- #include <ctype.h>
- #include "intr_loc.h"
- #include "mousedrv.h"
- #include "intr_gr.h"
-
- #define HISTORY_SIZE 10 /* History buffer length for GRGetGraphicLine. */
- #define GR_LINE_LEN 80 /* Maximum chars read by GRGetGraphicLine. */
-
- #define SVGA_SPECIAL 999 /* User installed BGI Super VGA driver. */
-
- #define POINT_SIZE 0.05 /* Size of + marker drawn. */
- #define POINT_TITLE 0.02 /* Distance between point title and + marker. */
-
- #define CURSOR_IMAGE_X 24
- #define CURSOR_IMAGE_Y 24
-
- #define CURSOR_TYPE_STACK_SIZE 20 /* Size of stack to save cursor types. */
- #define VIEW_PORT_STACK_SIZE 20 /* Depth of view port setting stack. */
- #define TEXT_SETTING_STACK_SIZE 10 /* Depth of text setting stack. */
-
- #define MAP_UP_X(x) ((((x) - GRPanFactorX) << GRZoomFactor) + GRWidth2)
- #define MAP_UP_Y(y) ((((y) - GRPanFactorY) << GRZoomFactor) + GRHeight2)
- #define MAP_DN_X(x) ((((x) - GRPanFactorX) >> GRIZoomFactor) + GRWidth2)
- #define MAP_DN_Y(y) ((((y) - GRPanFactorY) >> GRIZoomFactor) + GRHeight2)
- #define INVMAP_UP_X(x) ((((x) - GRWidth2) >> GRZoomFactor) + GRPanFactorX)
- #define INVMAP_UP_Y(y) ((((y) - GRHeight2) >> GRZoomFactor) + GRPanFactorY)
- #define INVMAP_DN_X(x) ((((x) - GRWidth2) << GRIZoomFactor) + GRPanFactorX)
- #define INVMAP_DN_Y(y) ((((y) - GRHeight2) << GRIZoomFactor) + GRPanFactorY)
-
- int GRScreenMaxX, GRScreenMaxY; /* The maximum resolution of the screen. */
- int GRScreenMaxColors; /* The maximum # of colors available. */
- IntrRType GRScreenAspect = 1.0; /* Screen aspect ratio (pixel width/height). */
- int GRCurrentCursorX, GRCurrentCursorY; /* Cursor current position. */
- int GRFontName, GRFontSize; /* Global information on font used. */
- int GRDrawText; /* If can not zoom down text, force draw. */
- int GRGraphMode = 0, GRGraphDriver = 0; /* What driver/mode are we in. */
-
- static int GRScreenMaxX2, GRScreenMaxY2; /* Half of maximum resolution. */
- static VoidPtr GRPutImage = NULL; /* If not null, used to save getimage. */
- static char *GRBGIDriverPath = ""; /* Where to look for BGI drivers. */
- static char *CursorImageBuffer; /* Cursor shape. */
- static int ScreenCursorColor; /* Graphic and text (in graphic screen). */
- static int OldStdOut; /* So we could recover it when exit from graph mode. */
- static int GRScreenGraphicMode;
- static char GRSVGAUserName[10];
- static int GRSVGAUserMode = 1;
- static int GRTextSize = 1; /* Current text size: 1 = 8x8, 2 = 16x16 etc.. */
- static int GRWidth2 = 100;
- static int GRHeight2 = 100;
- static int GRMinX = 0;
- static int GRMinY = 0;
- static int GRZoomFactor = 0;
- static int GRIZoomFactor = 0;
- static int GRPanFactorX = 0;
- static int GRPanFactorY = 0;
- static struct text_info TextInfo; /* So we can restore starting text mode. */
- static int ViewPortStackPtr = 0;
- static struct viewporttype far ViewPortStack[VIEW_PORT_STACK_SIZE];
- static int TextSettingStackPtr = 0;
- static struct textsettingstype TextSettingStack[TEXT_SETTING_STACK_SIZE];
- IntrInt2PtrFunc GlblGetChFunc = IntrGetEventWait;
-
- static char HistoryBuffer[HISTORY_SIZE][GR_LINE_LEN + 1];
- static int HistoryBufLen = 0;
-
- static int GRGetKey(void);
-
- /****************************************************************************
- * Routine to be called for the user installed driver: *
- ****************************************************************************/
- static int huge detectVGA(void)
- {
- return GRSVGAUserMode;
- }
-
- /****************************************************************************
- * Routine to install the Super VGA information. *
- * Note GraphDriver must be set to SVGA_SPECIAL for this to take affect. *
- ****************************************************************************/
- void GRInstallSVGA(char *NameMode)
- {
- char *p;
-
- p = strtok(NameMode, ".");
- strcpy(GRSVGAUserName, p);
-
- p = strtok(NULL, ".");
- sscanf(p, "%d", &GRSVGAUserMode);
-
- GRGraphDriver = SVGA_SPECIAL;
- }
-
- /****************************************************************************
- * Routine to set the path to the BGI drivers location. *
- ****************************************************************************/
- void GRSetBGIPath(char *BGIPath)
- {
- GRBGIDriverPath = strdup(BGIPath);
- }
-
- /****************************************************************************
- * Routine to set default driver (0 autodetect). *
- ****************************************************************************/
- void GRSetDefaultDriver(int GraphDriver)
- {
- GRGraphDriver = GraphDriver;
- }
-
- /****************************************************************************
- * Routine to reset all the system to starting condition : *
- ****************************************************************************/
- void GRInitGraph(void)
- {
- int IsSVGA = FALSE;
- int i, j, GRScreenErrorCode;
- unsigned char far
- *BiosMode = (unsigned char far *) MK_FP(0x40, 0x49);
-
- if (GRScreenGraphicMode) return;
- gettextinfo(&TextInfo);
-
- ViewPortStackPtr = 0; /* Make sure view port stack is empty. */
-
- /* For some wierd reason, some machines waits much more than expected on */
- /* the first delay. Lets do it now, so people will consider it part of */
- /* the initialization (make it a feature...)... */
- delay(1);
-
- if (GRGraphDriver != SVGA_SPECIAL) {
- if (GRGraphDriver == 0) {
- /* Use autodetect feature of graphic library to see what we have.*/
- detectgraph(&GRGraphDriver, &GRGraphMode);
- if (GRGraphDriver < 0) {
- IntrFatalError("Auto detect: No graphics device detected.");
- }
- }
- }
-
- /* Put in the following any graphic driver specific setup: */
- switch (GRGraphDriver) {
- case CGA:
- GRGraphMode = CGAHI;
- break;
- case ATT400:
- GRGraphMode = ATT400HI;
- break;
- case EGA:
- GRGraphMode = EGAHI;
- break;
- case EGA64:
- GRGraphMode = EGA64HI;
- break;
- case EGAMONO:
- GRGraphMode = EGAMONOHI;
- break;
- case HERCMONO:
- GRGraphMode = HERCMONOHI;
- /* Use 2nd page as aux mem! */
- GRPutImage = (VoidPtr) MK_FP(0xb800, 0x0000);
- break;
- case VGA:
- GRGraphMode = VGAHI;
- break;
- case SVGA_SPECIAL:
- IsSVGA = TRUE;
- installuserdriver(GRSVGAUserName, detectVGA);
- GRGraphDriver = DETECT;
- GRGraphMode = GRSVGAUserMode;
- break;
- default:
- IntrFatalError("Requested graphic device is not supported");
- break;
- }
-
- initgraph(&GRGraphDriver, &GRGraphMode, GRBGIDriverPath);
- if (IsSVGA) GRGraphDriver = SVGA_SPECIAL;
-
- GRScreenErrorCode = graphresult(); /* Read result of initialization. */
- if (GRScreenErrorCode != grOk) { /* Error occured during init. */
- IntrFatalError("Graphics System Error: can not intialize.");
- }
-
- GRScreenMaxColors = getmaxcolor() + 1; /* Read maximum number of colors. */
- ScreenCursorColor = (GRScreenMaxColors > 1 ? GRScreenMaxColors - 1 :
- GRScreenMaxColors);
-
- GRScreenMaxX = getmaxx(); /* Read size of screen. */
- GRScreenMaxY = getmaxy();
- GRCurrentCursorX = GRScreenMaxX2 = GRScreenMaxX / 2;
- GRCurrentCursorY = GRScreenMaxY2 = GRScreenMaxY / 2;
- getaspectratio(&i, &j); /* Read the hardware aspect. */
- GRScreenAspect = ((IntrRType) i) / j;
- setaspectratio(i, i); /* Disable the aspect ratio affect. */
-
- GRFontName = DEFAULT_FONT;
- GRFontSize = 1;
-
- /* Prepare the cursor (Arrow) image : */
- cleardevice();
- GRSetColor(ScreenCursorColor);
- GRSetLineStyle(SOLID_LINE, 0, NORM_WIDTH);
- GRSLine(0, 0, CURSOR_IMAGE_X, CURSOR_IMAGE_Y);
- j = CURSOR_IMAGE_X / 3;
- for (i = 1; i <= 7; i++) GRSLine(0, 0, j, j + i);/* Draw the arrow head. */
- j = CURSOR_IMAGE_Y / 3;
- for (i = 1; i <= 7; i++) GRSLine(0, 0, j + i, j);
-
- CursorImageBuffer = _IntrMalloc(imagesize(0, 0, CURSOR_IMAGE_X,
- CURSOR_IMAGE_Y));
- getimage(0, 0, CURSOR_IMAGE_X, CURSOR_IMAGE_Y, CursorImageBuffer);
-
- GRClearAllScreen();
-
- GRSetSTextStyle(DEFAULT_FONT, HORIZ_DIR, 1);
-
- switch (GRGraphDriver) {
- case CGA:
- case ATT400:
- case EGA:
- case EGA64:
- case EGAMONO:
- case VGA:
- MouseSetResolution(1000);
- break;
- case SVGA_SPECIAL:
- MouseSetResolution(4000);
- break;
- case HERCMONO:
- *BiosMode = 6;
- /* Compensate on the text mode the mouse knows about as */
- /* hercules is not supported by the mouse driver! */
- MouseSetResolution(1000);
- break;
- }
-
- GRScreenGraphicMode = TRUE;
- i = open("nul", O_WRONLY); /* Redirect the stdout to nul: (no ^C...). */
- fflush(stdout);
- OldStdOut = dup(1);
- dup2(i, 1);
- close(i);
- }
-
- /****************************************************************************
- * Routine to close and shutdown graphic mode : *
- ****************************************************************************/
- void GRCloseGraph(void)
- {
- if (!GRScreenGraphicMode) return;
- closegraph(); /* Return the system to text mode. */
- GRScreenGraphicMode = FALSE;
- dup2(OldStdOut, 1); /* Recover stdout to its regular status. */
- close(OldStdOut);
-
- textmode(TextInfo.currmode);
- }
-
- /****************************************************************************
- * Routine to set line style parameters. *
- ****************************************************************************/
- void GRSetLineStyle(int LineStyle, unsigned int Pattern, int Thickness)
- {
- setlinestyle(LineStyle, Pattern, Thickness);
- }
-
- /****************************************************************************
- * Routine to set fill style parameters. *
- ****************************************************************************/
- void GRSetFillStyle(int Pattern, int Color)
- {
- setfillstyle(Pattern, Color);
- }
-
- /****************************************************************************
- * Routine to set write mode parameters. *
- ****************************************************************************/
- void GRSetWriteMode(int DrawMode)
- {
- setwritemode(DrawMode);
- }
-
- /****************************************************************************
- * Routine to set text horizontal and vertical justification. *
- ****************************************************************************/
- void GRSetTextJustify(int HorizCenter, int VertCenter)
- {
- settextjustify(HorizCenter, VertCenter);
- }
-
- /****************************************************************************
- * Routine to set zoom factor for drawing. *
- * Zoom factor of 0 means regular drawing while each inc/decremenet zooms *
- * up/down respectively by a factor of 2. *
- ****************************************************************************/
- void GRSetZoomFactor(int ZoomFactor)
- {
- GRZoomFactor = ZoomFactor;
- GRIZoomFactor = -GRZoomFactor;
- }
-
- /****************************************************************************
- * Routine to set pan factors for drawing space. *
- ****************************************************************************/
- void GRSetPanFactors(int PanFactorX, int PanFactorY)
- {
- GRPanFactorX = PanFactorX;
- GRPanFactorY = PanFactorY;
- }
-
- /****************************************************************************
- * Routine to set text drawing parameters, in drawing space. *
- ****************************************************************************/
- void GRSetTextStyle(int GRFontName, int Direction, int Size)
- {
- GRTextSize = Size + GRZoomFactor;
-
- settextstyle(GRFontName, Direction, 1 << (MAX(GRTextSize, 1) - 1));
- }
-
- /****************************************************************************
- * Routine to set text drawing parameters, in screen space. *
- ****************************************************************************/
- void GRSetSTextStyle(int GRFontName, int Direction, int Size)
- {
- settextstyle(GRFontName, Direction, Size);
- }
-
- /****************************************************************************
- * Routine to set text drawing parameters. *
- ****************************************************************************/
- unsigned GRGetImageBufferSize(int x1, int y1, int x2, int y2)
- {
- return imagesize(x1, y1, x2, y2);
- }
-
- /****************************************************************************
- * Routine to set text drawing parameters. *
- ****************************************************************************/
- void GRGetImageBuffer(int x1, int y1, int x2, int y2, VoidPtr Buffer)
- {
- getimage(x1, y1, x2, y2, Buffer);
- }
-
- /****************************************************************************
- * Routine to set text drawing parameters. *
- ****************************************************************************/
- void GRPutImageBuffer(int x1, int y1, VoidPtr Buffer)
- {
- putimage(x1, y1, Buffer, COPY_PUT);
- }
-
- /****************************************************************************
- * Routine to XOR a rectangle area on screen using current color. *
- ****************************************************************************/
- void GRXORRectangle(int x1, int y1, int x2, int y2)
- {
- int i;
- struct linesettingstype lineinfo;
-
- getlinesettings(&lineinfo);
-
- setwritemode(XOR_PUT);
- setlinestyle(SOLID_LINE, 0, NORM_WIDTH);
-
- for (i = y1; i <= y2; i++)
- line(x1, i, x2, i);
-
- setwritemode(COPY_PUT);
- setlinestyle(lineinfo.linestyle, lineinfo.upattern, lineinfo.thickness);
- }
-
- /****************************************************************************
- * External reference for the mappings. *
- ****************************************************************************/
- int GRMapX(int x)
- {
- return (GRZoomFactor > 0 ? MAP_UP_X(x) : MAP_DN_X(x)) + GRMinX;
- }
-
- int GRMapY(int y)
- {
- return (GRZoomFactor > 0 ? MAP_UP_Y(y) : MAP_DN_Y(y)) + GRMinY;
- }
-
- /****************************************************************************
- * External reference for the inverse mapping. *
- ****************************************************************************/
- int GRInvMapX(int x)
- {
- x -= GRMinX;
- return (GRZoomFactor > 0 ? INVMAP_UP_X(x) : INVMAP_DN_X(x));
- }
-
- int GRInvMapY(int y)
- {
- y -= GRMinY;
- return (GRZoomFactor > 0 ? INVMAP_UP_Y(y) : INVMAP_DN_Y(y));
- }
-
- /****************************************************************************
- * Routine to draw a line, in Object spaces. *
- ****************************************************************************/
- void GRLine(int x1, int y1, int x2, int y2)
- {
- if (GRZoomFactor > 0) {
- moveto(MAP_UP_X(x1), MAP_UP_Y(y1));
- lineto(MAP_UP_X(x2), MAP_UP_Y(y2));
- }
- else {
- moveto(MAP_DN_X(x1), MAP_DN_Y(y1));
- lineto(MAP_DN_X(x2), MAP_DN_Y(y2));
- }
- }
-
- /****************************************************************************
- * Routine to move to a new position, in Object space. *
- ****************************************************************************/
- void GRMoveTo(int x, int y)
- {
- if (GRZoomFactor > 0)
- moveto(MAP_UP_X(x), MAP_UP_Y(y));
- else
- moveto(MAP_DN_X(x), MAP_DN_Y(y));
- }
-
- /****************************************************************************
- * Routine to draw to a new position, in Object space. *
- ****************************************************************************/
- void GRLineTo(int x, int y)
- {
- if (GRZoomFactor > 0)
- lineto(MAP_UP_X(x), MAP_UP_Y(y));
- else
- lineto(MAP_DN_X(x), MAP_DN_Y(y));
- }
-
- /****************************************************************************
- * Routine to move to a new position, in Screen (pixels) space. *
- ****************************************************************************/
- void GRSMoveTo(int x, int y)
- {
- moveto(x, y);
- }
-
- /****************************************************************************
- * Routine to draw to a new position, in Screen (pixels) space. *
- ****************************************************************************/
- void GRSLineTo(int x, int y)
- {
- lineto(x, y);
- }
-
- /****************************************************************************
- * Routine to draw to a new position, in Screen (pixels) space. *
- ****************************************************************************/
- void GRSLine(int x1, int y1, int x2, int y2)
- {
- line(x1, y1, x2, y2);
- }
-
- /****************************************************************************
- * Routine to move to a new position relative to current one, as in Object *
- * space. *
- ****************************************************************************/
- void GRMoveRel(int x, int y)
- {
- if (GRZoomFactor > 0)
- moverel(x << GRZoomFactor, y << GRZoomFactor);
- else
- moverel(x >> GRIZoomFactor, y >> GRIZoomFactor);
- }
-
- /****************************************************************************
- * Routine to line to a new position relative to current one, as in Object *
- * space. *
- ****************************************************************************/
- void GRLineRel(int x, int y)
- {
- if (GRZoomFactor > 0)
- linerel(x << GRZoomFactor, y << GRZoomFactor);
- else
- linerel(x >> GRIZoomFactor, y >> GRIZoomFactor);
- }
-
- /****************************************************************************
- * Routine to move to a new position relative to current one, as in Screen *
- * space (pixel coords.). *
- ****************************************************************************/
- void GRSMoveRel(int x, int y)
- {
- moverel(x, y);
- }
-
- /****************************************************************************
- * Routine to line to a new position relative to current one, as in Screen *
- * space (pixel coords.). *
- ****************************************************************************/
- void GRSLineRel(int x, int y)
- {
- linerel(x, y);
- }
-
- /****************************************************************************
- * Routine to draw a new polyline and fill it if Fill, in screen space. *
- ****************************************************************************/
- void GRPoly(int n, int *Points, int Fill)
- {
- int i, ii;
-
- if (GRZoomFactor > 0)
- for (i = 0; i < n; i++) {
- ii = i << 1;
- Points[ii] = MAP_UP_X(Points[ii]);
- Points[ii + 1] = MAP_UP_Y(Points[ii + 1]);
- }
- else
- for (i = 0; i < n; i++) {
- ii = i << 1;
- Points[ii] = MAP_DN_X(Points[ii]);
- Points[ii + 1] = MAP_DN_Y(Points[ii + 1]);
- }
-
- if (Fill) {
- /* There is a problem with BLACK color that fillpoly sometime does */
- /* not clear the border properly, so we need to redo it by drawpoly. */
- fillpoly(n, Points);
- drawpoly(n, Points);
- }
- else
- drawpoly(n, Points);
- }
-
- /****************************************************************************
- * Routine to draw a bar, in drawing space. *
- ****************************************************************************/
- void GRBar(int x1, int y1, int x2, int y2)
- {
- if (GRZoomFactor > 0)
- bar(MAP_UP_X(x1), MAP_UP_Y(y1), MAP_UP_X(x2), MAP_UP_Y(y2));
- else
- bar(MAP_DN_X(x1), MAP_DN_Y(y1), MAP_DN_X(x2), MAP_DN_Y(y2));
- }
-
- /****************************************************************************
- * Routine to draw a bar, in screen space. *
- ****************************************************************************/
- void GRSBar(int x1, int y1, int x2, int y2)
- {
- bar(x1, y1, x2, y2);
- }
-
- /****************************************************************************
- * Routine to draw a circle, in drawing space. *
- ****************************************************************************/
- void GRCircle(int x, int y, int r)
- {
- if (GRZoomFactor > 0)
- circle(MAP_UP_X(x), MAP_UP_Y(y), r << GRZoomFactor);
- else
- circle(MAP_DN_X(x), MAP_DN_Y(y), r >> GRIZoomFactor);
- }
-
- /****************************************************************************
- * Routine to draw an arc, in drawing space. *
- * As the Y axes is inverted the Angles should be inverted as well. *
- ****************************************************************************/
- void GRArc(int x, int y, int StAngle, int EndAngle, int r)
- {
- if (GRZoomFactor > 0)
- arc(MAP_UP_X(x), MAP_UP_Y(y), -EndAngle, -StAngle, r << GRZoomFactor);
- else
- arc(MAP_DN_X(x), MAP_DN_Y(y), -EndAngle, -StAngle, r >> GRIZoomFactor);
- }
-
- /****************************************************************************
- * Routine to draw the given text in given drawing space coordinates. *
- ****************************************************************************/
- IntrBType GRDrawingText(void)
- {
- return GRTextSize > 0 || GRDrawText;
- }
-
- /****************************************************************************
- * Routine to draw the given text in given drawing space coordinates. *
- ****************************************************************************/
- void GRText(int x, int y, char *s)
- {
- /* If text can not be zoom down and we are not forced to draw - dont. */
- if (GRTextSize < 1 && !GRDrawText) return;
-
- if (GRZoomFactor > 0)
- outtextxy(MAP_UP_X(x), MAP_UP_Y(y), s);
- else
- outtextxy(MAP_DN_X(x), MAP_DN_Y(y), s);
- }
-
- /****************************************************************************
- * Routine to draw the given text in given screen space coordinates. *
- ****************************************************************************/
- void GRSText(int x, int y, char *s)
- {
- outtextxy(x, y, s);
- }
-
- /****************************************************************************
- * Routine to draw the given text in given screen space coordinates. *
- * A Black shadow is drawn for the given string. *
- ****************************************************************************/
- void GRSTextShadow(int x, int y, int Color, char *s)
- {
- GRSetColor(BLACK);
- outtextxy(x + 2, y + 2, s);
- GRSetColor(Color);
- outtextxy(x, y, s);
- }
-
- /****************************************************************************
- * Routine to get string width in pixel. *
- ****************************************************************************/
- int GRGetTextWidth(char *Str)
- {
- return textwidth(Str);
- }
-
- /****************************************************************************
- * Routine to get string height in pixel. *
- ****************************************************************************/
- int GRGetTextHeight(char *Str)
- {
- return textheight(Str);
- }
-
- /****************************************************************************
- * Routine to push current font type and text attributes. *
- ****************************************************************************/
- void GRPushTextSetting(void)
- {
- if (TextSettingStackPtr >= TEXT_SETTING_STACK_SIZE)
- IntrFatalError("Text setting stack overflow.");
-
- gettextsettings(&TextSettingStack[TextSettingStackPtr++]);
- }
-
- /****************************************************************************
- * Routine to pop current font type and text attributes. *
- ****************************************************************************/
- void GRPopTextSetting(void)
- {
- if (--TextSettingStackPtr < 0)
- IntrFatalError("Text setting stack underflow.");
-
- settextstyle(TextSettingStack[TextSettingStackPtr].font,
- TextSettingStack[TextSettingStackPtr].direction,
- TextSettingStack[TextSettingStackPtr].charsize);
- settextjustify(TextSettingStack[TextSettingStackPtr].horiz,
- TextSettingStack[TextSettingStackPtr].vert);
- }
-
- /****************************************************************************
- * Routine to set color to color within range. *
- ****************************************************************************/
- void GRSetColor(int Color)
- {
- if (Color >= GRScreenMaxColors)
- Color = Color % (GRScreenMaxColors - 1) + 1;
- setcolor(Color);
- }
-
- /****************************************************************************
- * Routine to get current active color. *
- ****************************************************************************/
- int GRGetColor(void)
- {
- return getcolor();
- }
-
- /****************************************************************************
- * Routine to set one color index RGB values (EGA/VGA only). *
- ****************************************************************************/
- void GRSetRGBPalette(int Index, int Red, int Green, int Blue)
- {
- setrgbpalette(Index, Red, Green, Blue);
- }
-
- /****************************************************************************
- * Routine to draw the cursor as an arrow. *
- ****************************************************************************/
- void GRPutArrowCursor(int x, int y)
- {
- putimage(x, y, CursorImageBuffer, XOR_PUT);
- }
-
- /*****************************************************************************
- * Routine to clear all the screen. *
- *****************************************************************************/
- void GRClearAllScreen(void)
- {
- setviewport(0, 0, GRScreenMaxX, GRScreenMaxY, FALSE);
- cleardevice();
- }
-
- /*****************************************************************************
- * Routine to clear given rectangle viewport. *
- *****************************************************************************/
- void GRClearViewPort(int x1, int y1, int x2, int y2)
- {
- struct viewporttype viewport;
-
- getviewsettings(&viewport);
-
- setviewport(x1, y1, x2, y2, TRUE);
- clearviewport();
-
- setviewport(viewport.left, viewport.top, viewport.right, viewport.bottom,
- viewport.clip);
- }
-
- /*****************************************************************************
- * Routine to set given rectangle viewport. *
- *****************************************************************************/
- void _GRSetViewPort(int x1, int y1, int x2, int y2)
- {
- setviewport(x1, y1, x2, y2, TRUE);
- }
-
- /*****************************************************************************
- * Routine to set given rectangle viewport. *
- *****************************************************************************/
- void _GRSetViewPort2(int x1, int y1, int x2, int y2, IntrBType Clip)
- {
- setviewport(x1, y1, x2, y2, Clip);
- }
-
- /*****************************************************************************
- * Routine to set given rectangle viewport. *
- *****************************************************************************/
- void GRGetViewPort(int *x1, int *y1, int *x2, int *y2)
- {
- struct viewporttype viewstruct;
-
- getviewsettings(&viewstruct);
- *x1 = viewstruct.left;
- *x2 = viewstruct.right;
- *y1 = viewstruct.top;
- *y2 = viewstruct.bottom;
- }
-
- /*****************************************************************************
- * Routine to set given rectangle viewport. *
- *****************************************************************************/
- void GRSetViewPort(int x1, int y1, int x2, int y2)
- {
- setviewport(x1, y1, x2, y2, TRUE);
- GRWidth2 = (x2 - x1) / 2;
- GRHeight2 = (y2 - y1) / 2;
- GRMinX = x1;
- GRMinY = y1;
- }
-
- /*****************************************************************************
- * Routine to push current view port. *
- *****************************************************************************/
- void GRPushViewPort(void)
- {
- if (ViewPortStackPtr >= VIEW_PORT_STACK_SIZE)
- IntrFatalError("View port stack overflow.");
-
- getviewsettings(&ViewPortStack[ViewPortStackPtr++]);
- }
-
- /*****************************************************************************
- * Routine to pop current view port. *
- *****************************************************************************/
- void GRPopViewPort(void)
- {
- if (--ViewPortStackPtr < 0)
- IntrFatalError("View port stack underflow.");
-
- setviewport(ViewPortStack[ViewPortStackPtr].left,
- ViewPortStack[ViewPortStackPtr].top,
- ViewPortStack[ViewPortStackPtr].right,
- ViewPortStack[ViewPortStackPtr].bottom,
- ViewPortStack[ViewPortStackPtr].clip);
- GRWidth2 = (ViewPortStack[ViewPortStackPtr].right -
- ViewPortStack[ViewPortStackPtr].left) / 2;
- GRHeight2 = (ViewPortStack[ViewPortStackPtr].bottom -
- ViewPortStack[ViewPortStackPtr].top) / 2;
- GRMinX = ViewPortStack[ViewPortStackPtr].left;
- GRMinY = ViewPortStack[ViewPortStackPtr].top;
- }
-
- /*****************************************************************************
- * Routine to read one line terminated by <Enter> and visualized on graphic *
- * screen. *
- * Full line editing is supported which includes: *
- * 1. Right and left arrows to move along the line. *
- * 2. Up and down arrows to circle a history buffer. *
- * 3. Delete to delete current character. *
- * 4. Insert to toggle Insert/Overwrite mode. *
- * 5. Backspace to delete character before current one. *
- * 6. Home/End to move to beginning/End of string respectively. *
- * 7. Return to accept current line. *
- * 8. Esc to clear current line. *
- * *
- * Notes: *
- * If s is not empty it is used as starting string. *
- * Line is drawn starting from position x, y on screen, WindowLen positions. *
- * s buffer is assumed to be of SLen length. *
- *****************************************************************************/
- void GRGetGraphicLine(int WindowID, int x, int y, char s[], int SLen,
- int WindowLen, int ForeColor, int BackColor)
- {
- static int i,
- Insert = TRUE;
- int NextKey, Xstep, xt,
- Len = strlen(s),
- CursorPos = Len,
- FirstVisible = 0,
- FirstTime = TRUE,
- EndOfString = FALSE,
- HistoryBufCrnt = -1;
- char DisplayLine[GR_LINE_LEN];
- struct textsettingstype oldtext;
- _IntrWindowStruct
- *Window = WindowID ? _IntrFindWndwUsingID(WindowID) : NULL;
-
- gettextsettings(&oldtext);
- settextstyle(DEFAULT_FONT, HORIZ_DIR, 1);
- settextjustify(LEFT_TEXT, TOP_TEXT);
-
- Xstep = textwidth("M"); /* Get the width in pixels of current font. */
-
- while (!EndOfString) {
- /* Can not display the whole string, so set first visible char: */
- FirstVisible = CursorPos > WindowLen - 2 ? CursorPos - WindowLen + 2
- : 0;
- /* Prepare the part of s to be displayed: */
- strncpy(DisplayLine, &s[FirstVisible], GR_LINE_LEN - 1);
- DisplayLine[MIN(WindowLen, GR_LINE_LEN - 1)] = 0;
-
- GRSetColor(ForeColor);
- outtextxy(x, y, DisplayLine);
- xt = x + (CursorPos - FirstVisible) * Xstep;
- if (Insert)
- GRXORRectangle(xt, y + 7, xt + 7, y + 8);
- else
- GRXORRectangle(xt, y, xt + 7, y + 8);
-
- if ((NextKey = GRGetKey()) != KEY_REFRESH || FirstTime) {
- if (Insert)
- GRXORRectangle(xt, y + 7, xt + 7, y + 8);
- else
- GRXORRectangle(xt, y, xt + 7, y + 8);
- GRSetColor(BackColor); /* Erase the string and the cursor: */
- outtextxy(x, y, DisplayLine);
- }
- FirstTime = FALSE;
-
- switch (NextKey) {
- case KEY_BSPACE:
- if (CursorPos == 0) {
- GRTone(1000, 100); /* Do some noise... */
- break;
- }
- movmem(&s[CursorPos], &s[CursorPos - 1], Len - CursorPos + 1);
- CursorPos--;
- Len--;
- break;
- case KEY_DELETE:
- if (CursorPos >= Len) {
- GRTone(1000, 100); /* Do some noise... */
- break;
- }
- movmem(&s[CursorPos + 1], &s[CursorPos], Len - CursorPos);
- Len--;
- break;
- case KEY_RIGHT:
- if (CursorPos >= Len) {
- GRTone(1000, 100); /* Do some noise... */
- break;
- }
- CursorPos++;
- break;
- case KEY_LEFT:
- if (CursorPos <= 0) {
- GRTone(1000, 100); /* Do some noise... */
- break;
- }
- CursorPos--;
- break;
- case KEY_UP:
- if (HistoryBufLen == 0) {
- GRTone(1000, 100); /* Do some noise... */
- break;
- }
-
- if (++HistoryBufCrnt >= HistoryBufLen) HistoryBufCrnt = 0;
-
- strcpy(s, HistoryBuffer[HistoryBufCrnt]);
- CursorPos = Len = strlen(s);
- break;
- case KEY_DOWN:
- if (HistoryBufLen == 0) {
- GRTone(1000, 100); /* Do some noise... */
- break;
- }
-
- if (--HistoryBufCrnt < 0) HistoryBufCrnt = HistoryBufLen - 1;
-
- strcpy(s, HistoryBuffer[HistoryBufCrnt]);
- CursorPos = Len = strlen(s);
- break;
- case KEY_RETURN:
- EndOfString = TRUE;
- break;
- case KEY_ESC:
- Len = 0; /* Clear everything. */
- CursorPos = 0;
- s[0] = 0;
- break;
- case KEY_HOME:
- CursorPos = 0;
- break;
- case KEY_END:
- CursorPos = Len;
- break;
- case KEY_INSERT:
- Insert = !Insert;
- break;
- case KEY_NONE:
- GRTone(1000, 100); /* Do some noise... */
- GRTone(500, 200);
- break;
- case KEY_REFRESH: /* Internal event to intr_lib. */
- if (Window != NULL) {
- _GRSetViewPort(Window -> BBox.Xmin, Window -> BBox.Ymin,
- Window -> BBox.Xmax, Window -> BBox.Ymax);
- x = TEXT_BORDER,
- y = Window -> BBox.Ymax - Window -> BBox.Ymin -
- TEXT_BORDER - GRGetTextHeight("M");
- }
- settextstyle(DEFAULT_FONT, HORIZ_DIR, 1);
- settextjustify(LEFT_TEXT, TOP_TEXT);
- break;
- default: /* Regular ascii char. */
- if (Insert) {
- movmem(&s[CursorPos], &s[CursorPos + 1],
- Len - CursorPos + 1);
- Len++;
- }
- else if (CursorPos == Len)
- Len++; /* We are on last character. */
- s[CursorPos++] = NextKey;
- if (CursorPos == Len) s[CursorPos] = 0;
- break;
- }
- if (SLen <= Len - 1) { /* End of buffer - can not save more info. */
- Len = SLen - 1;
- if (CursorPos > Len) CursorPos = Len;
- GRTone(1000, 100); /* Do some noise... */
- }
- }
-
- /* Update the history buffer: */
- for (i = HISTORY_SIZE - 1; i > 0; i--)
- strncpy(HistoryBuffer[i], HistoryBuffer[i - 1], GR_LINE_LEN);
- strncpy(HistoryBuffer[0], s, GR_LINE_LEN);
- HistoryBufLen = MIN(HISTORY_SIZE, HistoryBufLen + 1);
-
- settextstyle(oldtext.font, oldtext.direction, oldtext.charsize);
- settextjustify(oldtext.horiz, oldtext.vert);
- }
-
- /*****************************************************************************
- * Sets the function invoked to get a kbd event in GRGetKey. *
- * NULL will recover the internal default - IntrGetEventWait. *
- *****************************************************************************/
- void GRSetGetKeyFunc(IntrInt2PtrFunc GetChFunc)
- {
- if (GetChFunc == NULL)
- GlblGetChFunc = IntrGetEventWait;
- else
- GlblGetChFunc = GetChFunc;
- }
-
- /*****************************************************************************
- * Get a key from keyboard, and translating operational keys into special *
- * codes (>255). *
- *****************************************************************************/
- static int GRGetKey(void)
- {
- int x, y;
-
- /* Detach the keyboard from moving the mouse so keyboard can be used to */
- /* edit the input line instead. */
- _IntrDetachKbdFromMouse = TRUE;
- while (GlblGetChFunc(&x, &y) != INTR_EVNT_KEY);
- _IntrDetachKbdFromMouse = FALSE;
-
- if (x >= 256) {
- switch (x - 256) { /* Extended code - get the next extended char. */
- case 72:
- return KEY_UP;
- case 80:
- return KEY_DOWN;
- case 75:
- return KEY_LEFT;
- case 77:
- return KEY_RIGHT;
- case 71:
- return KEY_HOME;
- case 79:
- return KEY_END;
- case 83:
- return KEY_DELETE;
- case 82:
- return KEY_INSERT;
- case KEY_REFRESH - 256:
- return KEY_REFRESH;
- }
- }
- else {
- switch (x) {
- case 8:
- return KEY_BSPACE;
- case 10:
- case 13:
- return KEY_RETURN;
- case 27:
- return KEY_ESC;
- default:
- if (isprint(x)) return x;
- }
- }
-
- return KEY_NONE;
- }
-
- /*****************************************************************************
- * Routine to make some sound with given Frequency, Time milliseconds: *
- *****************************************************************************/
- void GRTone(int Frequency, int Time)
- {
- sound(Frequency);
- delay(Time);
- nosound();
- }
-