home *** CD-ROM | disk | FTP | other *** search
- /* -*- C -*-
- ** Astrolog (Version 4.40) File: xdevice.c
- **
- ** IMPORTANT NOTICE: The graphics database and chart display routines
- ** used in this program are Copyright (C) 1991-1995 by Walter D. Pullen
- ** (astara@u.washington.edu). Permission is granted to freely use and
- ** distribute these routines provided one doesn't sell, restrict, or
- ** profit from them in any way. Modification is allowed provided these
- ** notices remain with any altered or edited versions of the program.
- **
- ** The main planetary calculation routines used in this program have
- ** been Copyrighted and the core of this program is basically a
- ** conversion to C of the routines created by James Neely as listed in
- ** Michael Erlewine's 'Manual of Computer Programming for Astrologers',
- ** available from Matrix Software. The copyright gives us permission to
- ** use the routines for personal use but not to sell them or profit from
- ** them in any way.
- **
- ** The PostScript code within the core graphics routines are programmed
- ** and Copyright (C) 1992-1993 by Brian D. Willoughby
- ** (brianw@sounds.wa.com). Conditions are identical to those above.
- **
- ** The extended accurate ephemeris databases and formulas are from the
- ** calculation routines in the program "Placalc" and are programmed and
- ** Copyright (C) 1989,1991,1993 by Astrodienst AG and Alois Treindl
- ** (alois@azur.ch). The use of that source code is subject to
- ** regulations made by Astrodienst Zurich, and the code is not in the
- ** public domain. This copyright notice must not be changed or removed
- ** by any user of this program.
- **
- ** Initial programming 8/28,30, 9/10,13,16,20,23, 10/3,6,7, 11/7,10,21/1991.
- ** X Window graphics initially programmed 10/23-29/1991.
- ** PostScript graphics initially programmed 11/29-30/1992.
- ** Last code change made 1/29/1995.
- */
-
- /* $VER: $Id: xdevice.c,v 1.2 1995/07/02 22:22:49 tf Exp $ */
-
- #include "astrolog.h"
-
-
- #ifdef GRAPH
- /*
- ******************************************************************************
- ** Bitmap File Routines.
- ******************************************************************************
- */
-
- /* Write the bitmap array to a previously opened file in a format that */
- /* can be read in by the Unix X commands bitmap and xsetroot. The 'mode' */
- /* parameter defines how much white space is put in the file. */
-
- void WriteXBitmap(file, name, mode)
- FILE *file;
- char *name, mode;
- {
- int x, y, i, temp = 0;
- _int value;
-
- fprintf(file, "#define %s_width %d\n" , name, gs.xWin);
- fprintf(file, "#define %s_height %d\n", name, gs.yWin);
-
- fprintf(file, "static %s %s_bits[] = {", mode != 'V' ? "char" : "short", name);
-
- for (y = 0; y < gs.yWin; y++)
- {
- x = 0;
-
- do {
-
- /* Process each row, eight columns at a time. */
-
- if (y + x > 0)
- fprintf(file, ",");
-
- if (temp == 0)
- fprintf(file, "\n%s", mode == 'N' ? " " : (mode == 'C' ? " " : ""));
-
- value = 0;
-
- for (i = (mode != 'V' ? 7 : 15); i >= 0; i--)
- value = (value << 1) + (!(FBmGet(gi.bm, x+i, y)^(gs.fInverse*15))^gs.fInverse && (x + i < gs.xWin));
-
- if (mode == 'N')
- putc(' ', file);
-
- fprintf(file, "0x");
-
- if (mode == 'V')
- fprintf(file, "%c%c", ChHex(value >> 12), ChHex((value >> 8) & 15));
-
- fprintf(file, "%c%c", ChHex((value >> 4) & 15), ChHex(value & 15));
- temp++;
-
- /* Is it time to skip to the next line while writing the file yet? */
-
- if ((mode == 'N' && temp >= 12) ||
- (mode == 'C' && temp >= 15) ||
- (mode == 'V' && temp >= 11))
- temp = 0;
-
- x += (mode != 'V' ? 8 : 16);
-
- } while (x < gs.xWin);
- }
- fprintf(file, "};\n");
- }
-
-
- /* Write the bitmap array to a previously opened file in a simple boolean */
- /* Ascii rectangle, one char per pixel, where '#' represents an off bit and */
- /* '-' an on bit. The output format is identical to the format generated by */
- /* the Unix bmtoa command, and it can be converted into a bitmap with atobm. */
-
- void WriteAscii(file)
- FILE *file;
- {
- int x, y, i;
-
- for (y = 0; y < gs.yWin; y++)
- {
- for (x = 0; x < gs.xWin; x++)
- {
- i = FBmGet(gi.bm, x, y);
- if (gs.fColor)
- putc(ChHex(i), file);
- else
- putc(i ? '-' : '#', file);
- }
- putc('\n', file);
- }
- }
-
-
- /* Write the bitmap array to a previously opened file in the bitmap format */
- /* used in Microsoft Windows for its .bmp extension files. This is a pretty */
- /* efficient format, only requiring a small header, and one bit per pixel */
- /* for monochrome graphics, or four bits per pixel for full color. */
-
- void WriteBmp(file)
- FILE *file;
- {
- int x, y;
- dword value;
-
- /* Note that we sometimes only write a part of the full bitmap to disk */
- /* during the call, as done when the bitmap is being generated in bands. */
-
- if (gi.yBand == 0 || gi.yOffset + gi.yBand >= gs.yWin)
- {
- /* BitmapFileHeader */
-
- PutByte('B'); PutByte('M');
- PutLong(14+40 + (gs.fColor ? 64 : 8) + (long)4*gs.yWin*((gs.xWin-1 >> (gs.fColor ? 3 : 5))+1));
- PutWord(0); PutWord(0);
- PutLong(14+40 + (gs.fColor ? 64 : 8));
-
- /* BitmapInfo / BitmapInfoHeader */
-
- PutLong(40);
- PutLong(gs.xWin); PutLong(gs.yWin);
- PutWord(1); PutWord(gs.fColor ? 4 : 1);
- PutLong(0 /*BI_RGB*/); PutLong(0);
- PutLong(0); PutLong(0);
- PutLong(0); PutLong(0);
-
- /* RgbQuad */
-
- if (gs.fColor)
- {
- for (x = 0; x < 16; x++)
- {
- PutByte(RGBB(rgbbmp[x])); PutByte(RGBG(rgbbmp[x]));
- PutByte(RGBR(rgbbmp[x])); PutByte(0);
- }
- }
- else
- {
- PutLong(0);
- PutByte(255); PutByte(255); PutByte(255); PutByte(0);
- }
- }
-
- /* Data */
-
- for (y = (gi.yBand ? Min(gi.yBand, gs.yWin - gi.yOffset) : gs.yWin) - 1; y >= 0; y--)
- {
- value = 0;
-
- for (x = 0; x < gs.xWin; x++)
- {
- if ((x & (gs.fColor ? 7 : 31)) == 0 && x > 0)
- {
- PutLong(value);
- value = 0;
- }
-
- if (gs.fColor)
- value |= (dword)FBmGet(gi.bm, x, y) << ((x & 7 ^ 1) << 2);
-
- else
- if (FBmGet(gi.bm, x, y))
- value |= (dword)1 << (x & 31 ^ 7);
- }
- PutLong(value);
- }
- }
-
-
- /* Begin the work of creating a graphics file. Prompt for a filename if */
- /* need be, and if valid, create the file and open it for writing. */
-
- void BeginFileX()
- {
- char line[cchSzDef];
-
- if (gi.szFileOut == NULL && (
- #ifdef PS
- gi.fEps ||
- #endif
- gs.fMeta || (gs.fBitmap && gs.chBmpMode == 'B'))) {
- sprintf(line, "(It is recommended to specify an extension of '.%s'.)\n",
- gs.fBitmap ? "bmp" :
- #ifdef PS
- (gi.fEps ? "eps" : "wmf")
- #else
- "wmf"
- #endif
- );
- PrintSzScreen(line);
- }
-
- loop
- {
- if (gi.szFileOut == NULL)
- {
- sprintf(line, "Enter name of file to write %s to", gs.fBitmap ? "bitmap" :
- (gs.fPS ? "PostScript" : "metafile"));
- InputString(line, line);
- gi.szFileOut = line;
- }
- gi.file = fopen(gi.szFileOut, gs.fPS ? "w" : "wb");
-
- if (gi.file != NULL)
- break;
-
- else {
- PrintWarning("Couldn't create output file.");
- gi.szFileOut = NULL;
- }
- }
- }
-
-
- /* Finish up the work of creating a graphics file. This basically consists */
- /* of just calling the appropriate routine to actually write the data in */
- /* memory to a file for bitmaps and metafiles, although for PostScript we */
- /* just close file as we were already writing while creating the chart. */
-
- void EndFileX()
- {
- char sz[cchSzDef];
-
- if (gs.fBitmap)
- {
- if (gi.yBand)
- {
- sprintf(sz, "Writing part %d of chart bitmap to file.", gi.yOffset / gi.yBand + 1);
- PrintNotice(sz);
- }
- else
- PrintNotice("Writing chart bitmap to file.");
-
- if (gs.chBmpMode == 'B')
- WriteBmp(gi.file);
-
- else if (gs.chBmpMode == 'A')
- WriteAscii(gi.file);
-
- else
- WriteXBitmap(gi.file, gi.szFileOut, gs.chBmpMode);
- }
- #ifdef PS
- else if (gs.fPS)
- PsEnd();
- #endif
-
- #ifdef META
- else {
- PrintNotice("Writing metafile to disk.");
- WriteMeta(gi.file);
- }
- #endif
-
- if (!gs.fBitmap || gi.yOffset == 0)
- {
- fclose(gi.file);
- gi.yBand = 0;
- }
- }
-
-
- #ifdef PS
- /*
- ******************************************************************************
- ** PostScript File Routines.
- ******************************************************************************
- */
-
- /* Table of PostScript header alias lines used by the program. */
-
- CONST char FAR szPsFunctions[] =
- "/languagelevel where{pop languagelevel}{1}ifelse\
- 2 lt{\n\
- /sf{exch findfont exch\
- dup type/arraytype eq{makefont}{scalefont}ifelse setfont}bind def\n\
- /rf{gsave newpath\n\
- 4 -2 roll moveto\
- dup 0 exch rlineto exch 0 rlineto neg 0 exch rlineto closepath\n\
- fill grestore}bind def\n\
- /rc{newpath\n\
- 4 -2 roll moveto\
- dup 0 exch rlineto exch 0 rlineto neg 0 exch rlineto closepath\n\
- clip newpath}bind def\n\
- }{/sf/selectfont load def/rf/rectfill load def\
- /rc/rectclip load def}ifelse\n\
- /center{0 begin gsave dup 4 2 roll\
- translate newpath 0 0 moveto\
- false charpath flattenpath pathbbox\
- /URy exch def/URx exch def/LLy exch def/LLx exch def\
- URx LLx sub 0.5 mul LLx add neg URy LLy sub 0.5 mul LLy add neg\
- 0 0 moveto rmoveto\
- show grestore end}bind def\n\
- /center load 0 4 dict put\n\
- /c{setrgbcolor}bind def\n\
- /d{moveto 0 0 rlineto}bind def\n\
- /l{4 2 roll moveto lineto}bind def\n\
- /t{lineto}bind def\n\
- /el{newpath matrix currentmatrix 5 1 roll translate scale\
- 0 0 1 0 360 arc setmatrix stroke}bind def\n";
-
-
- /* Write a command to flush the PostScript buffer. */
-
- void PsStrokeForce()
- {
- if (gi.cStroke > 0) { /* render any existing path */
- fprintf(gi.file, "stroke\n");
- gi.cStroke = 0;
- gi.xPen = -1; /* Invalidate PolyLine cache */
- }
- }
-
-
- /* Indicate that a certain number of PostScript commands have been done. */
-
- void PsStroke(n)
- int n;
- {
- gi.cStroke += n;
- if (gi.cStroke > 2000) /* Whenever we reach a certain limit, flush. */
- PsStrokeForce();
- }
-
-
- /* Set the type of line end to be used by PostScript commands. If linecap */
- /* is true, then the line ends are rounded, otherwise they are squared. */
-
- void PsLineCap(fLineCap)
- bool fLineCap;
- {
- if (fLineCap != gi.fLineCap) {
- PsStrokeForce();
- fprintf(gi.file, "%d setlinecap\n", fLineCap);
- gi.fLineCap = fLineCap;
- }
- }
-
-
- /* Set the dash length to be used by PostScript line commands. */
-
- void PsDash(dashoff)
- int dashoff;
- {
- if (dashoff != gi.nDash) {
- PsStrokeForce();
- if (dashoff)
- fprintf(gi.file, "[%d %d", PSMUL, dashoff * PSMUL);
- else
- fprintf(gi.file, "[");
- fprintf(gi.file, "]0 setdash\n");
- gi.nDash = dashoff;
- }
- }
-
-
- /* Set a linewidth size to be used by PostScript figure primitive commands. */
-
- void PsLineWidth(linewidth)
- int linewidth;
- {
- if ((real)linewidth != gi.rLineWid) {
- PsStrokeForce();
- fprintf(gi.file, "%d setlinewidth\n", linewidth);
- gi.rLineWid = (real)linewidth;
- }
- }
-
-
- /* Set a system font and size to be used by PostScript text commands. */
-
- void PsFont(psfont)
- int psfont;
- {
- int z;
-
- if (psfont != gi.nFont && gs.fFont) {
- if (psfont <= 2) {
- z = psfont == 1 ? 32*PSMUL : 23*PSMUL;
- fprintf(gi.file, "/Astro[%d 0 0 -%d 0 0]sf\n", z, z);
- } else if (psfont == 3) {
- z = 26*PSMUL;
- fprintf(gi.file, "/Times-Roman[%d 0 0 -%d 0 0]sf\n", z, z);
- } else {
- z = 10*PSMUL;
- fprintf(gi.file, "/Courier[%d 0 0 -%d 0 0]sf\n", z, z);
- }
- gi.nFont = psfont;
- }
- }
-
-
- /* Prompt the user for the name of a file to write the PostScript file to */
- /* (if not already specified), open it, and write out file header info. */
-
- void PsBegin()
- {
- fprintf(gi.file, "%%!PS-Adobe-2.0");
- if (gi.fEps)
- fprintf(gi.file, " EPSF-2.0");
- fprintf(gi.file, "\n%%%%Title: %s\n", gi.szFileOut);
- fprintf(gi.file, "%%%%Creator: %s %s\n", szAppName, szVersionCore);
- fprintf(gi.file, "%%%%CreationDate: %s\n", szDateCore);
-
- if (gi.fEps)
- {
- fprintf(gi.file, "%%%%BoundingBox: 0 0 %d %d\n", gs.xWin, gs.yWin);
- fprintf(gi.file, "%%%%EndComments\n");
- fprintf(gi.file, "%%%%BeginSetup\n");
- fprintf(gi.file, szPsFunctions, 6 * PSMUL, 6 * PSMUL);
- fprintf(gi.file, "%%%%EndSetup\n");
- fprintf(gi.file, "0 0 %d %d rc\n", gs.xWin, gs.yWin);
- }
-
- else
- {
- fprintf(gi.file, "%%%%Pages: 1 1\n");
- fprintf(gi.file, "%%%%DocumentFonts: (atend)\n");
- fprintf(gi.file, "%%%%BoundingBox: %d %d %d %d\n", PSGUTTER, PSGUTTER,
- (int)(gs.xInch*72.0+rRound)-PSGUTTER,
- (int)(gs.yInch*72.0+rRound)-PSGUTTER);
- fprintf(gi.file, "%%%%EndComments\n");
- fprintf(gi.file, "%%%%BeginProcSet: common\n");
- fprintf(gi.file, szPsFunctions, 6 * PSMUL, 6 * PSMUL);
- fprintf(gi.file, "%%%%EndProcSet\n");
- fprintf(gi.file, "%%%%Page: 1 1\n");
- }
-
- PsFont(2);
- fprintf(gi.file, "gsave\n");
- PsLineWidth(gi.nPenWid/2);
- gi.xPen = -1;
- PrintNotice("Creating PostScript chart file.");
- }
-
-
- /* Write out trailing information to the PostScript file and close it. */
-
- void PsEnd()
- {
- PsStrokeForce();
-
- if (gi.fEps)
- fprintf(gi.file, "%%%%EOF\n");
-
- else
- {
- fprintf(gi.file, "showpage\n");
- fprintf(gi.file, "%%%%PageTrailer\n");
- fprintf(gi.file, "%%%%Trailer\n");
- fprintf(gi.file, "%%%%DocumentFonts: Times-Roman\n");
- if (gs.fFont) {
- fprintf(gi.file, "%%%%+ Courier\n");
- fprintf(gi.file, "%%%%+ Astro\n");
- }
- }
- fclose(gi.file);
- }
- #endif /* PS */
-
-
- #ifdef META
- /*
- ******************************************************************************
- ** Metafile Routines.
- ******************************************************************************
- */
-
- /* Output one 16 bit or 32 bit value into the metafile buffer stream. */
-
- void MetaWord(w)
- word w;
- {
- char sz[cchSzDef];
-
- if ((hpbyte)gi.pwMetaCur - gi.bm >= gi.cbMeta) {
- sprintf(sz, "Metafile would be more than %ld bytes.", gi.cbMeta);
- PrintError(sz);
- Terminate(tcFatal);
- }
- *gi.pwMetaCur = w;
- gi.pwMetaCur++;
- }
-
- void MetaLong(l)
- long l;
- {
- MetaWord(WLo(l));
- MetaWord(WHi(l));
- }
-
-
- /* Output any necessary metafile records to make the current actual */
- /* settings of line color, fill color, etc, be those that we know are */
- /* desired. This is generally called by the primitives routines before */
- /* any figure record is actually written into a metafile. We wait until */
- /* the last moment before changing any settings to ensure that we don't */
- /* output any unnecessary records, e.g. two select colors in a row. */
-
- void MetaSelect()
- {
- if (gi.kiLineDes != gi.kiLineAct)
- {
- MetaSelectObject(gi.kiLineDes);
- gi.kiLineAct = gi.kiLineDes;
- }
-
- if (gi.kiFillDes != gi.kiFillAct)
- {
- MetaSelectObject(16*4 + gi.kiFillDes);
- gi.kiFillAct = gi.kiFillDes;
- }
-
- if (gi.nFontDes != gi.nFontAct)
- {
- MetaSelectObject(16*5 + gi.nFontDes);
- gi.nFontAct = gi.nFontDes;
- }
-
- if (gi.kiTextDes != gi.kiTextAct)
- {
- MetaTextColor(rgbbmp[gi.kiTextDes]);
- gi.kiTextAct = gi.kiTextDes;
- }
-
- if (gi.nAlignDes != gi.nAlignAct)
- {
- MetaTextAlign(gi.nAlignDes);
- gi.nAlignAct = gi.nAlignDes;
- }
-
- gi.xPen = -1; /* Invalidate PolyLine cache */
- }
-
-
- /* Output initial metafile header information into our metafile buffer. */
- /* We also setup and create all pen, brush, and font objects that may */
- /* possibly be used in the generation and playing of the picture. */
-
- void MetaInit()
- {
- int i, j, k;
-
- gi.pwMetaCur = (word HFAR *)gi.bm;
-
- /* Placable Metaheader */
-
- MetaLong(0x9AC6CDD7L);
- MetaWord(0); /* Not used */
- MetaWord(0); MetaWord(0);
- MetaWord(gs.xWin); MetaWord(gs.yWin);
- MetaWord(gs.xWin/6); /* Units per inch */
- MetaLong(0L); /* Not used */
- MetaWord(0x9AC6 ^ 0xCDD7 ^ gs.xWin ^ gs.yWin ^ gs.xWin/6); /* Checksum */
-
- /* Metaheader */
-
- MetaWord(1); /* Metafile type */
- MetaWord(9); /* Size of header in words */
- MetaWord(0x300); /* Windows version */
- MetaLong(0L); /* Size of entire metafile in words */
- MetaWord(16*5+1+(gs.fFont>0)*4); /* Number of objects in metafile */
- MetaLong(17L); /* Size of largest record in words */
- MetaWord(0); /* Not used */
-
- /* Setup */
-
- MetaEscape(17);
- MetaLong(LFromBB('A', 's', 't', 'r')); /* "Astr" */
- MetaWord(4); /* Creator */
- MetaLong(14L); /* Bytes in string */
- MetaLong(LFromBB('A', 's', 't', 'r')); /* "Astr" */
- MetaLong(LFromBB('o', 'l', 'o', 'g')); /* "olog" */
- MetaLong(LFromBB(' ', '4', '.', '4')); /* " 4.4" */
- MetaWord(WFromBB('0', 0)); /* "0" */
- MetaSaveDc();
- MetaWindowOrg(0, 0);
- MetaWindowExt(gs.xWin, gs.yWin);
- MetaBkMode(1 /* Transparent */);
-
- /* Colors */
-
- for (j = 1; j <= 4; j++)
- {
- for (i = 0; i < 16; i++)
- {
- k = j <= 1 ? gi.nPenWid : 0;
- MetaCreatePen(j <= 2 ? 0 : j-2 /* PS_SOLID; PS_DASH; PS_DOT */,
- k, rgbbmp[i]);
- }
- }
-
- for (i = 0; i < 16; i++) {
- MetaCreateBrush(0 /* BS_SOLID */, rgbbmp[i]);
- }
-
- MetaCreateBrush(1 /* BS_NULL */, 0L);
-
- /* Fonts */
-
- if (gs.fFont)
- {
- MetaCreateFont(5, 0, -8*gi.nScale, 2 /* Symbol Charset */);
- MetaWord(WFromBB(1 /* Draft */, 1 | 0x10 /* Fixed | Roman */));
- MetaLong(LFromBB('W', 'i', 'n', 'g'));
- MetaLong(LFromBB('d', 'i', 'n', 'g'));
- MetaWord(WFromBB('s', 0));
-
- MetaCreateFont(8, 0, -6*gi.nScale, 0 /* Ansi Charset */);
- MetaWord(WFromBB(0 /* Default */, 2 | 0x10 /* Variable | Roman */));
- MetaLong(LFromBB('T', 'i', 'm', 'e'));
- MetaLong(LFromBB('s', ' ', 'N', 'e'));
- MetaLong(LFromBB('w', ' ', 'R', 'o'));
- MetaLong(LFromBB('m', 'a', 'n', 0));
-
- MetaCreateFont(6, 6*METAMUL, 10*METAMUL, 0 /* Ansi Charset */);
- MetaWord(WFromBB(1 /* Draft */, 1 | 0x30 /* Fixed | Modern */));
- MetaLong(LFromBB('C', 'o', 'u', 'r'));
- MetaLong(LFromBB('i', 'e', 'r', ' '));
- MetaLong(LFromBB('N', 'e', 'w', 0));
-
- MetaCreateFont(8, 0, -11*gi.nScale, 0 /* Ansi Charset */);
- MetaWord(WFromBB(0 /* Default */, 2 | 0 /* Variable | Don't Care */));
- MetaLong(LFromBB('A', 's', 't', 'r'));
- MetaLong(LFromBB('o', '-', 'S', 'e'));
- MetaLong(LFromBB('m', 'i', 'B', 'o'));
- MetaLong(LFromBB('l', 'd', 0, 0));
- }
- }
-
-
- /* Output trailing records to indicate the end of the metafile and then */
- /* actually write out the entire buffer to the specifed file. */
-
- void WriteMeta(file)
- FILE *file;
- {
- word HFAR *w;
-
- #if FALSE
- int i;
-
- for (i = 16*5+1+(gs.fFont>0)*4; i >= 0; i--) {
- MetaDeleteObject(i);
- }
- #endif
-
- MetaRestoreDc();
- MetaRecord(3, 0); /* End record */
-
- *(long HFAR *)(gi.bm + 22 + 6) = ((long)((hpbyte)gi.pwMetaCur - gi.bm) - 22) / 2;
-
- for (w = (word HFAR *)gi.bm; w < gi.pwMetaCur; w++) {
- PutWord(*w);
- }
- }
- #endif /* META */
-
-
- #ifdef MOUSE
- #ifdef PC
- /*
- ******************************************************************************
- ** Mouse Routines.
- ******************************************************************************
- */
-
- static union REGS dosreg;
-
-
- /* Setup and initialize the PC graphics mouse, returning the number of */
- /* buttons available, or zero for no mouse at all. Passed in is the pixel */
- /* size of the screen the mouse pointer is to be contained within. */
-
- int MouseInit(x, y)
- int x, y;
- {
- int dx, cBtn;
-
- if (!gs.fMouse)
- return 0;
- dosreg.x.ax = 0;
- int86(0x33, &dosreg, &dosreg);
- if (!(gs.fMouse = dosreg.x.ax))
- return 0;
- cBtn = dosreg.x.bx;
- dx = x - 1;
- dosreg.x.ax = 7;
- dosreg.x.cx = 0;
- dosreg.x.dx = dx;
- int86(0x33, &dosreg, &dosreg);
- dx = y - 1;
- dosreg.x.ax = 8;
- dosreg.x.cx = 0;
- dosreg.x.dx = dx;
- int86(0x33, &dosreg, &dosreg);
- return cBtn;
- }
-
-
- /* Turn on or hide the PC graphics mouse pointer. */
-
- void MouseShow(fShow)
- bool fShow;
- {
- int ax;
-
- if (!gs.fMouse)
- return;
- ax = fShow ? 1 : 2;
- dosreg.x.ax = ax;
- int86(0x33, &dosreg, &dosreg);
- }
-
-
- /* Fill out the current status of the mouse: its horizontal and vertical */
- /* position, and button press status. We return false if the mouse hasn't */
- /* changed any from the last call (assuming that the previous values are */
- /* stored in the input parameters) or if the mouse isn't active at all. */
-
- bool MouseStatus(x, y, btn)
- int *x, *y, *btn;
- {
- int bx, cx, dx, fChange;
-
- if (!gs.fMouse)
- return fFalse;
-
- dosreg.x.ax = 3;
- int86(0x33, &dosreg, &dosreg);
-
- bx = dosreg.x.bx;
- cx = dosreg.x.cx;
- dx = dosreg.x.dx;
-
- fChange = (cx != *x || dx != *y || bx != *btn);
-
- *x = cx;
- *y = dx;
- *btn = bx;
- return fChange;
- }
- #endif /* PC */
- #endif /* MOUSE */
- #endif /* GRAPH */
-
- /* xdevice.c */
-