1GRX graphics library user's manual, version 2.0 2=============================================== 3 4 5THIS FILE IS UNDER CONSTRUCTION!!!!!!! 6Use the 1.03 user's manual for description of the library functions and 7consult "grx20.h" 8 9The most important differences: 101) COLORS ARE LONG!!!! 112) NO WIDE LINES AND PATTERNED FILLS YET! 123) NO GrFindBestFont(), NO INTEGER FONT MAGNIFICATION, 13 BUT FONTS CAN BE SCALED 144) ARCS HAVE AN EXTRA PARAMETER, WHICH IS THE STYLE FOR CLOSING THEM 15 16 17==================== Don't read after this ============================= 18 19 20Abstract 21 22LIBGRX is a graphics library for DJGPP or Turbo C programs. (The Turbo 23C version was tested using TC++ 1.01) Currently it supports VGA (32768, 24256 or 16 colors), EGA (16 colors), 8514/A (256 colors) and S3-based (256 25colors) cards. Planned future improvements include support for Hercules 26cards as well. It is upward compatible with the graphics library in DJGPP 27(the C part, no C++ classes). It can use the same drivers as the graphics 28library in DJGPP or it can work with a new driver format supporting 29programmable number of colors as well. 30 31 32Data types, function declarations 33 34All public data structures and graphics primitives meant for usage by 35the application program are declared/prototyped in the header files (in the 36'include' sub-directory): 37 38GRDRIVER.H graphics driver format specifications 39MOUSEX.H cursor, mouse and keyboard handling 40GRX.H drawing-related structures and functions 41GRXFILE.H file formats and file access routines 42GRXFONT.H format of a font when loaded into memory 43 44 45Setting video modes 46 47Before a program can do any graphics drawing it has to configure the 48display adapter of the PC for the desired graphics mode. It is done with the 49'GrSetMode' function as follows: 50 51#ifdef __cplusplus 52void GrSetMode(int which,int width=0,int height=0,int colors=0); 53#else 54void GrSetMode(int which,...); 55#endif 56 57The 'mode' parameter can be one of the following constants, declared in 58"grx.h": 59 60typedef enum { 61GR_80_25_text, 62GR_default_text, 63GR_width_height_text, 64GR_biggest_text, 65GR_320_200_graphics, 66GR_default_graphics, 67GR_width_height_graphics, 68GR_biggest_noninterlaced_graphics, 69GR_biggest_graphics, 70GR_width_height_color_graphics 71 72 73 74 75 76LIBGRX graphics library user's manual 3 77 78 79} GR_graphics_modes; 80 81The 'GR_width_height_text' and 'GR_width_height_graphics' modes require 82the two optional size arguments, and the 'GR_width_height_color_graphics' mode 83requires all three optional arguments. A call with any other mode does not 84require any of the optional arguments. 85 86NOTE: the 'GR_width_height_color_graphics' mode is a new mode supported only 87if: (1) you have a new format graphics driver (see the accompanying 88documentation in the file "DRIVERS.DOC"), and (2) you have a recent (version 891.06, dated after the middle of April 1992) copy of GO32 which knows how to 90deal with the new driver format. 91 92New format graphics drivers operating in the proper environment (see above) 93can provide a table of the supported text and graphics modes using: 94 95void GrGetDriverModes(GR_DRIVER_MODE_ENTRY **ttable,GR_DRIVER_MODE_ENTRY **gtable) 96 97The arguments 'ttable' and 'gtable' should be addresses of pointers to the 98'GR_DRIVER_MODE_ENTRY' structure defined in the include file "grdriver.h". 99Upon return the pointer variables will point to two arrays of these 100structures, one for the text modes, the other for graphics. The 101'GR_DRIVER_MODE_ENTRY' structure has the following fields: 102 103typedef struct { 104unsigned short width; 105unsigned short height; 106unsigned short number_of_colors; 107unsigned char BIOS_mode; 108unsigned char special; 109} GR_DRIVER_MODE_ENTRY; 110 111The first four structure members should be obvious, but the 'special' 112field may deserve some explanation. It is non-zero if the driver does some 113special "tricks" to put the card into the desired mode. An example might be 114the 43 row EGA text mode: for this first the "standard" 80x25 text mode is 115set up and then the character generator is re-loaded with a smaller font. 116If the 'special' field is zero then the driver simply invokes the INT 10 117function 0 BIOS routine with the mode in the 'BIOS_mode' slot. 118 119A user-defined function can be invoked every time the video mode is 120changed (i.e. 'GrSetMode' is called). This function should not take any 121parameters and its return value (if any) is ignored. It can be installed 122(for all subsequent 'GrSetMode' calls) with the: 123 124void GrSetModeHook(void (*callback)(void)); 125 126function. The current graphics mode (one of the valid 'mode' argument values 127for 'GrSetMode') can be obtained with the: 128 129int GrCurrentMode(void); 130 131 132 133 134 135LIBGRX graphics library user's manual 4 136 137 138function, while the type of the installed graphics adapter can be determined 139with the 140 141int GrAdapterType(void); 142 143function. 'GrAdapterType' returns the type of the adapter as one of the 144following three symbolic constants (defined in "grx.h"): 145 146#define GR_VGA 0 /* VGA adapter */ 147#define GR_EGA 1 /* EGA adapter */ 148#define GR_HERC 2 /* Hercules mono adapter */ 149#define GR_8514A 3 /* 8514/A or compatible */ 150#define GR_S3 4 /* S3 graphics accelerator */ 151 152 153 154 155 156LIBGRX graphics library user's manual 5 157 158 159Graphics contexts 160 161The library supports a set of drawing regions called 'contexts' (the 162'GrContext' structure). These can be in video memory or in system memory. 163Contexts in system memory always have the same memory organization as the 164video memory. When 'GrSetMode' is called, a default context is created which 165maps to the whole graphics screen. Contexts are described by the 'GrContext' 166data structure: 167 168typedef struct _GR_context_ { 169char far *gc_baseaddr; /* base address of display memory */ 170long gc_frameaddr; /* upper left corner coordinate */ 171long gc_planeoffset; /* offset to next color plane */ 172int gc_lineoffset; /* offset to next scan line in bytes */ 173char gc_onscreen; /* is it in video memory ? */ 174char gc_memflags; /* memory allocation flags */ 175int gc_xmax; /* max X coord (width - 1) */ 176int gc_ymax; /* max Y coord (height - 1) */ 177int gc_xcliplo; /* low X clipping limit */ 178int gc_ycliplo; /* low Y clipping limit */ 179int gc_xcliphi; /* high X clipping limit */ 180int gc_ycliphi; /* high Y clipping limit */ 181int gc_usrxbase; /* user window min X coordinate */ 182int gc_usrybase; /* user window min Y coordinate */ 183int gc_usrwidth; /* user window width */ 184int gc_usrheight; /* user window height */ 185int gc_xoffset; /* X offset from root's base */ 186int gc_yoffset; /* Y offset from root's base */ 187struct _GR_context_ *gc_root; /* context which owns frame buf */ 188} GrContext; 189 190There is a subtype of the 'GrContext' structure. The structure 191'GrVidRAM' contains only the first slots of a context describing the memory 192layout of a context. This structure is used as a component of other more 193complex data structures in the library. 194 195typedef struct { 196char far *gc_baseaddr; /* base address of display memory */ 197long gc_frameaddr; /* upper left corner coordinate */ 198long gc_planeoffset; /* offset to next color plane */ 199int gc_lineoffset; /* offset to next scan line in bytes */ 200char gc_onscreen; /* is it in video memory ? */ 201char gc_memflags; /* memory allocation flags */ 202} GrVidRAM; 203 204The following four functions return information about the layout of and 205memory occupied by a graphics context of size 'width' by 'height' in the 206current graphics mode (as set up by 'GrSetMode'): 207 208int GrLineOffset(int width); 209int GrNumPlanes(void); 210 211 212 213 214 215LIBGRX graphics library user's manual 6 216 217 218long GrPlaneSize(int w,int h); 219long GrContextSize(int w,int h); 220 221'GrLineOffset' always returns the offset between successive pixel rows of the 222context in bytes. 'GrNumPlanes' returns the number of bitmap planes in the 223current graphics mode. 'GrContextSize' calculates the total amount of memory 224needed by a context, while 'GrPlaneSize' calculates the size of a bitplane in 225the context. The function: 226 227GrContext *GrCreateContext(int w,int h,char far *memory,GrContext *where); 228 229can be used to create a new context in system memory. The NULL pointer is also 230accepted as the value of the 'memory' and 'where' arguments, in this case the 231library allocates the necessary amount of memory internally. 232 233It is a general convention in the library that functions returning 234pointers to any LIBGRX specific data structure have a last argument (most of 235the time named 'where' in the prototypes) which can be used to pass the 236address of the data structure which should be filled with the result. If this 237'where' pointer has the value of NULL, then the library allocates space for 238the data structure internally. 239 240The function: 241 242GrContext *GrCreateSubContext(int x1,int y1,int x2,int y2,GrContext *parent,GrContext *where); 243 244creates a new sub-context which maps to a part of an existing context. The 245coordinate arguments ('x1' through 'y2') are interpreted relative to the 246parent context's limits. Pixel addressing is zero-based even in sub-contexts, 247i.e. the address of the top left pixel is (0,0) even in a sub-context which 248has been mapped onto the interior of its parent context. 249 250Sub-contexts can be resized, but not their parents (i.e. anything 251returned by 'GrCreateContext' or set up by 'GrSetMode' cannot be resized -- 252because this could lead to irrecoverable "loss" of drawing memory. The 253following function can be used for this purpose: 254 255void GrResizeSubContext(GrContext *context,int x1,int y1,int x2,int y2); 256 257The current context structure is stored in a static location in the 258library. (For efficiency reasons -- it is used quite frequently, and this way 259no pointer dereferencing is necessary.) The context stores all relevant 260information about the video organization, coordinate limits, etc... The 261current context can be set with the: 262 263void GrSetContext(GrContext *context); 264 265function. This function will reset the current context to the full graphics 266screen if it is passed the NULL pointer as argument. The value of the current 267context can be saved into a 'GrContext' structure pointed to by 'where' using: 268 269 270 271 272 273LIBGRX graphics library user's manual 7 274 275 276GrContext *GrSaveContext(GrContext *where); 277 278(Again, if 'where' is NULL, the library allocates the space.) Contexts can be 279destroyed with: 280 281void GrDestroyContext(GrContext *context); 282 283This function will free the memory occupied by the context only if it was 284allocated originally by the library. The next three functions set up and query 285the clipping limits associated with the context: 286 287void GrSetClipBox(int x1,int y1,int x2,int y2); 288void GrGetClipBox(int *x1p,int *y1p,int *x2p,int *y2p); 289void GrResetClipBox(void); 290 291'GrResetClipBox' sets the clipping limits to the limits of context. These are 292the limits set up initially when a context is created. The limits of the 293current context can be obtained using the following functions: 294 295int GrMaxX(void); 296int GrMaxY(void); 297int GrSizeX(void); 298int GrSizeY(void); 299 300The 'Max' functions return the biggest valid coordinate, while the 'Size' 301functions return a value one higher. The limits of the graphics screen 302(regardless of the current context) can be obtained with: 303 304int GrScreenX(void); 305int GrScreenY(void); 306 307 308Color management 309 310The library supports two models for color management. In the 'indirect' 311(or color table) mode colors can be allocated with the highest resolution 312supported by the hardware (EGA: 2 bits, VGA: 6 bits) with respect to the 313component color intensities. In the 'direct' or RGB mode color indices map 314directly into component color intensities with non-overlapping bitfields of 315the color index representing the component colors. The RGB mode is supported 316in 256 color and 32768 color VGA modes only (for 32768 colors this is the only 317mode because of the limitations of the VGA hardware with HiColor DAC). In RGB 318mode the color index maps to component color intensities as follows: 319 320256: rrrgggbb (3 bits for red and green, 2 for blue) 32132768: xrrrrrgggggbbbbb (5 bits for each component color) 322 323The RGB mode is not supported in 16 color EGA and VGA modes as there are 324too few available colors to provide adequate coverage. The advantage of the 325RGB mode is faster color allocation (no table lookup, DAC register 326 327 328 329 330 331LIBGRX graphics library user's manual 8 332 333 334programming, etc...) its disadvantage is the relatively crude approximation of 335the component color intensities. 336 337After the first 'GrSetMode' call two colors are always defined: black 338and white. The indices of these two colors are returned by the functions: 339 340int GrBlack(void); 341int GrWhite(void); 342 343NOTE: unlike the original DJGPP library, LIBGRX does not guarantee that the 344white color 345has the color index value of one. (GrBlack still returns 0). 346 347The library supports four write modes: write, XOR, logical OR and 348logical AND. These can be selected with OR-ing the color index with one of the 349following constants declared in "grx.h": 350 351#ifdef __TURBOC__ 352# define GrXOR 0x100 /* to "XOR" any color to the screen */ 353# define GrOR 0x200 /* to "OR" to the screen */ 354# define GrAND 0x300 /* to "AND" to the screen */ 355#endif 356#ifdef __GNUC__ /* changed for 16 bit colors */ 357# define GrXOR 0x10000 /* to "XOR" any color to the screen */ 358# define GrOR 0x20000 /* to "OR" to the screen */ 359# define GrAND 0x30000 /* to "AND" to the screen */ 360#endif 361#define GrWRITE 0 /* write color */ 362#define GrNOCOLOR (GrXOR | 0) /* GrNOCOLOR is used for "no" color */ 363 364NOTE: 'GrXOR' was declared to be "0x100" in the original DJGPP library, but 365its value had to be changed in LIBGRX in anticipation of the 32768 color VGA 366support. 367 368By convention, the no-op color is obtained by combining color index 0 (black) 369with the XOR operation. This no-op color has been defined in "grx.h" as 370'GrNOCOLOR'. 371 372The number of colors in the current graphics mode is returned by the: 373 374int GrNumColors(void); 375 376function, while the number of unused, available color can be obtained by 377calling: 378 379int GrNumFreeColors(void); 380 381Colors can be allocated with the: 382 383int GrAllocColor(int r,int g,int b); 384 385 386 387 388 389LIBGRX graphics library user's manual 9 390 391 392function (component intensities can range from 0 to 255), or with the: 393 394int GrAllocCell(void); 395 396function. In the second case the component intensities of the returned color 397can be set with: 398 399void GrSetColor(int color,int r,int g,int b); 400 401Both 'Alloc' functions return 'GrNOCOLOR' if there are no more free colors 402available. Additionally 'GrAllocCell' always returns 'GrNOCOLOR' when the 403color system is in RGB mode, as colors returned by 'GrAllocCell' are meant to 404be changed -- what is not supposed to be done in RGB mode. Also note that 405'GrAllocColor' operates much more efficiently in RGB mode, and that it never 406returns 'GrNOCOLOR' in this case. 407 408Color table entries can be freed (when not in RGB mode) by calling: 409 410void GrFreeColor(int color); 411 412The component intensities of any color can be queried using the function: 413 414void GrQueryColor(int c,int *r,int *g,int *b); 415 416Initially the color system is in color table (indirect) mode. (Except 417for the 32768 color VGA modes which are always in RGB mode.) 256 color VGA 418modes can be put into the RGB mode by calling: 419 420void GrSetRGBcolorMode(void); 421 422The color system can be reset (i.e. put back into color table mode if 423possible, all colors freed except for black and white) by calling: 424 425void GrResetColors(void); 426 427The function: 428 429void GrRefreshColors(void); 430 431reloads the currently allocated color values into the video hardware. This 432function is not needed in typical applications, unless the display adapter is 433programmed directly by the application. 434 435Graphics primitives 436 437The screen, the current context or the current clip box can be cleared 438(i.e.set toadesired backgroundcolor)by usingoneof thefollowingthree functions: 439 440void GrClearScreen(int bg); 441void GrClearContext(int bg); 442void GrClearClipBox(int bg); 443 444 445 446 447 448LIBGRX graphics library user's manual 10 449 450 451The following line drawing graphics primitives are supported by the library: 452 453void GrPlot(int x,int y,int c); 454void GrLine(int x1,int y1,int x2,int y2,int c); 455void GrHLine(int x1,int x2,int y,int c); 456void GrVLine(int x,int y1,int y2,int c); 457void GrBox(int x1,int y1,int x2,int y2,int c); 458void GrCircle(int xc,int yc,int r,int c); 459void GrEllipse(int xc,int yc,int xa,int ya,int c); 460void GrCircleArc(int xc,int yc,int r,int start,int end,int c); 461void GrEllipseArc(int xc,int yc,int xa,int ya,int start,int end,int c); 462void GrPolyLine(int numpts,int points[][2],int c); 463void GrPolygon(int numpts,int points[][2],int c); 464 465All primitives operate on the current graphics context. The last argument of 466these functions is always the color index to use for the drawing. The 467'HLine' and 'VLine' primitives are for drawing horizontal and vertical 468lines. They have been included in the library because they are more 469efficient than the general line drawing provided by 'GrLine'. The ellipse 470primitives can only draw ellipses with their major axis parallel with either 471the X or Y coordinate axis. They take the half X and Y axis length in the 472'xa' and 'ya' arguments. The arc (circle and ellipse) drawing functions take 473the start and end angles in tenths of degrees (i.e. meaningful range: 0 ... 4743600). The angles are interpreted counter-clockwise starting from the 475positive X axis. The polyline and polygon primitives take the address of an 476n by 2 coordinate array. The X values should be stored in the elements with 4770 second index, and the Y values in the elements with a second index value 478of 1. Coordinate arrays passed to the polygon primitives can either contain 479or omit the closing edge of the polygon -- the primitive will append it to 480the list if it is missing. 481 482The following filled primitives are available: 483 484void GrFilledBox(int x1,int y1,int x2,int y2,int c); 485void GrFramedBox(int x1,int y1,int x2,int y2,int wdt,const GrFBoxColors *c); 486void GrFilledCircle(int xc,int yc,int r,int c); 487void GrFilledEllipse(int xc,int yc,int xa,int ya,int c); 488void GrFilledCircleArc(int xc,int yc,int r,int start,int end,int c); 489void GrFilledEllipseArc(int xc,int yc,int xa,int ya,int start,int end,int c); 490void GrFilledPolygon(int numpts,int points[][2],int c); 491void GrFilledConvexPolygon(int numpts,int points[][2],int c); 492 493Similarly to the line drawing, all of the above primitives operate on 494the current graphics context. The 'GrFramedBox' primitive can be used to draw 495motif-like shaded boxes and "ordinary" framed boxes as well. The 'x1' through 496'y2' coordinates specify the interior of the box, the border is outside this 497area. The primitive uses five different colors for the interior and four 498borders of the box which are specified in the 'GrFBoxColors' structure: 499 500typedef struct { 501int fbx_intcolor; 502int fbx_topcolor; 503 504 505 506 507 508LIBGRX graphics library user's manual 11 509 510 511int fbx_rightcolor; 512int fbx_bottomcolor; 513int fbx_leftcolor; 514} GrFBoxColors; 515 516The 'GrFilledConvexPolygon' primitive can be used to fill convex polygons. It 517can also be used to fill some concave polygons whose boundaries do not 518intersect any horizontal scan line more than twice. All other concave polygons 519have to be filled with the (somewhat less efficient) 'GrFilledPolygon' 520primitive. This primitive can also be used to fill several disjoint non- 521overlapping polygons in a single operation. 522 523The current color value of any pixel in the current context can be obtained 524with: 525 526int GrPixel(int x,int y); 527 528Rectangular areas can be transferred within a context or between contexts by 529calling: 530 531void GrBitBlt(GrContext *dest,int x,int y,GrContext *source,int x1,int y1,int x2,int y2,int oper); 532 533The 'oper' argument should be one of supported color modes (write, XOR, OR, 534AND), it will control how the pixels from the source context are combined with 535the pixels in the destination context. If either the source or the destination 536context argument is the NULL pointer then the current context is used for that 537argument. 538 539 540Non-clipping graphics primitives 541 542There is a non-clipping version of some of the elementary primitives. 543These are somewhat more efficient than the regular versions. These are to be 544used only in situations when it is absolutely certain that no drawing will be 545performed beyond the boundaries of the current context. Otherwise the program 546will almost certainly crash! The reason for including these functions is that 547they are somewhat more efficient than the regular, clipping versions. ALSO 548NOTE: These function do not check for conflicts with the mouse cursor. (See 549the explanation about the mouse cursor handling later in this document.) The 550list of the supported non-clipping primitives: 551 552void GrPlotNC(int x,int y,int c); 553void GrLineNC(int x1,int y1,int x2,int y2,int c); 554void GrHLineNC(int x1,int x2,int y,int c); 555void GrVLineNC(int x,int y1,int y2,int c); 556void GrBoxNC(int x1,int y1,int x2,int y2,int c); 557void GrFilledBoxNC(int x1,int y1,int x2,int y2,int c); 558void GrFramedBoxNC(int x1,int y1,int x2,int y2,int wdt,const GrFBoxColors *c); 559void GrBitBltNC(GrContext *dst,int x,int y,GrContext *src,int x1,int y1,int x2,int y2,int oper); 560int GrPixelNC(int x,int y); 561 562 563 564 565 566LIBGRX graphics library user's manual 12 567 568 569Customized line drawing 570 571The basic line drawing graphics primitives described previously always 572draw continuous lines which are one pixel wide. There is another group of line 573drawing functions which can be used to draw wide and/or patterned lines. These 574functions have similar parameter passing conventions as the basic ones with 575one difference: instead of the color value a pointer to a structure of type 576'GrLineOption' has to be passed to them. The definition of the 'GrLineOption' 577structure: 578 579typedef struct { 580int lno_color; /* color used to draw line */ 581int lno_width; /* width of the line */ 582int lno_pattlen; /* length of the dash pattern */ 583unsigned char *lno_dashpat; /* draw/nodraw pattern */ 584} GrLineOption; 585 586The 'lno_pattlen' structure element should be equal to the number of 587alternating draw -- no draw section length values in the array pointed to by 588the 'lno_dashpat' element. The dash pattern array is assumed to begin with a 589drawn section. If the pattern length is equal to zero a continuous line is 590drawn. The available custom line drawing primitives: 591 592void GrCustomLine(int x1,int y1,int x2,int y2,const GrLineOption *o); 593void GrCustomBox(int x1,int y1,int x2,int y2,const GrLineOption *o); 594void GrCustomCircle(int xc,int yc,int r,const GrLineOption *o); 595void GrCustomEllipse(int xc,int yc,int xa,int ya,const GrLineOption *o); 596void GrCustomCircleArc(int xc,int yc,int r,int start,int end,const GrLineOption *o); 597void GrCustomEllipseArc(int xc,int yc,int xa,int ya,int start,int end,const GrLineOption *o); 598void GrCustomPolyLine(int numpts,int points[][2],const GrLineOption *o); 599void GrCustomPolygon(int numpts,int points[][2],const GrLineOption *o); 600 601 602Pattern filled graphics primitives 603 604The library also supports a pattern filled version of the basic filled 605primitives described above. These functions have similar parameter passing 606conventions as the basic ones with one difference: instead of the color value 607a pointer to an union of type 'GrPattern' has to be passed to them. The 608'GrPattern' union can contain either a bitmap or a pixmap fill pattern. The 609first integer slot in the union determines which type it is. Bitmap fill 610patterns are rectangular arrays of bits, each set bit representing the 611foreground color of the fill operation, and each zero bit representing the 612background. Both the foreground and background colors can be combined with any 613of the supported logical operations. Bitmap fill patterns have one 614restriction: their width must be eight pixels. Pixmap fill patterns are very 615similar to contexts, the data is transferred to the filled primitive using 616'BitBlt' operations. The relevant structure declarations (from "grx.h"): 617 618/* 619* BITMAP: a mode independent way to specify a fill pattern of two 620 621 622 623 624 625LIBGRX graphics library user's manual 13 626 627 628* colors. It is always 8 pixels wide (1 byte per scan line), its 629* height is user-defined. SET THE TYPE FLAG TO ZERO!!! 630*/ 631typedef struct { 632int bmp_ispixmap; /* type flag for pattern union */ 633int bmp_height; /* bitmap height */ 634unsigned char *bmp_data; /* pointer to the bit pattern */ 635int bmp_fgcolor; /* foreground color for fill */ 636int bmp_bgcolor; /* background color for fill */ 637int bmp_memflags; /* set if dynamically allocated */ 638} GrBitmap; 639 640/* 641* PIXMAP: a fill pattern stored in a layout identical to the video RAM 642* for filling using 'bitblt'-s. It is mode dependent, typically one 643* of the library functions is used to build it. KEEP THE TYPE FLAG 644* NONZERO!!! 645*/ 646typedef struct { 647int pxp_ispixmap; /* type flag for pattern union */ 648int pxp_width; /* pixmap width (in pixels) */ 649int pxp_height; /* pixmap height (in pixels) */ 650int pxp_oper; /* bitblt mode (SET, OR, XOR, AND) */ 651GrVidRAM pxp_source; /* source context for fill */ 652} GrPixmap; 653 654/* 655* Fill pattern union -- can either be a bitmap or a pixmap 656*/ 657typedef union { 658int gp_ispixmap; /* nonzero for pixmaps */ 659GrBitmap gp_bitmap; /* fill bitmap */ 660GrPixmap gp_pixmap; /* fill pixmap */ 661} GrPattern; 662 663#define gp_bmp_data gp_bitmap.bmp_data 664#define gp_bmp_height gp_bitmap.bmp_height 665#define gp_bmp_fgcolor gp_bitmap.bmp_fgcolor 666#define gp_bmp_bgcolor gp_bitmap.bmp_bgcolor 667 668#define gp_pxp_width gp_pixmap.pxp_width 669#define gp_pxp_height gp_pixmap.pxp_height 670#define gp_pxp_oper gp_pixmap.pxp_oper 671#define gp_pxp_source gp_pixmap.pxp_source 672 673Bitmap patterns can be easily built from initialized character arrays and 674static structures by the C compiler, thus no special support is included in 675the library for creating them. The only action required from the application 676program might be changing the foreground and background colors as needed. 677Pixmap patterns are more difficult to build as they replicate the layout of 678the video memory which changes for different video modes. For this reason the 679 680 681 682 683 684LIBGRX graphics library user's manual 14 685 686 687library provides three functions to create pixmap patterns in a mode- 688independent way: 689 690GrPattern *GrBuildPixmap(const char *pixels,int w,int h,const GrColorTableP colors); 691GrPattern *GrBuildPixmapFromBits(const char *bits,int w,int h,int fgc,int bgc); 692GrPattern *GrConvertToPixmap(GrContext *src); 693 694'GrBuildPixmap' build a pixmap from a two dimensional ('w' by 'h') array of 695characters. The elements in this array are used as indices into the color 696table specified with the argument 'colors'. (This means that pixmaps created 697this way can use at most 256 colors.) The color table pointer: 698 699typedef int *GrColorTableP; 700 701should point to an array of integers with the first element being the number 702of colors in the table and the color indices themselves starting with the 703second element. NOTE: any color modifiers (GrXOR, GrOR, GrAND) OR-ed to the 704elements of the color table are ignored. 705 706The 'GrBuildPixmapFromBits' function builds a pixmap fill pattern from bitmap 707data. It is useful if the width of the bitmap pattern is not eight as such 708bitmap patterns can not be used to build a 'GrBitmap' structure. 709 710The 'GrConvertToPixmap' function converts a graphics context to a pixmap fill 711pattern. It is useful when the pattern can be created with graphics drawing 712operations. NOTE: the pixmap pattern and the original context share the 713drawing RAM, thus if the context is redrawn the fill pattern changes as well. 714 715Fill patterns which were built by library routines can be destroyed when 716no longer needed (i.e. the space occupied by them can be freed) by calling: 717 718void GrDestroyPattern(GrPattern *p); 719 720NOTE: when pixmap fill patterns converted from contexts are destroyed, the 721drawing RAM is not freed. It is freed when the original context is destroyed. 722Fill patterns built by the application have to be destroyed by the application 723as well (if this is needed). 724 725The list of supported pattern filled graphics primitives is shown below. 726These functions are very similar to their solid filled counterparts, only 727their last argument is different: 728 729void GrPatternFilledPlot(int x,int y,GrPattern *p); 730void GrPatternFilledLine(int x1,int y1,int x2,int y2,GrPattern *p); 731void GrPatternFilledBox(int x1,int y1,int x2,int y2,GrPattern *p); 732void GrPatternFilledCircle(int xc,int yc,int r,GrPattern *p); 733void GrPatternFilledEllipse(int xc,int yc,int xa,int ya,GrPattern *p); 734void GrPatternFilledCircleArc(int xc,int yc,int r,int start,int end,GrPattern *p); 735void GrPatternFilledEllipseArc(int xc,int yc,int xa,int ya,int start,int end,GrPattern *p); 736void GrPatternFilledConvexPolygon(int numpts,int points[][2],GrPattern *p); 737void GrPatternFilledPolygon(int numpts,int points[][2],GrPattern *p); 738 739 740 741 742 743LIBGRX graphics library user's manual 15 744 745 746Strictly speaking the plot and line functions in the above group are not 747filled, but they have been included here for convenience. 748 749 750Patterned line drawing 751 752The custom line drawing functions introduced above also have a version 753when the drawn sections can be filled with a (pixmap or bitmap) fill pattern. 754To achieve this these functions must be passed both a custom line drawing 755option ('GrLineOption' structure) and a fill pattern ('GrPattern' union). 756These two have been combined into the 'GrLinePattern' structure: 757 758typedef struct { 759GrPattern *lnp_pattern; /* fill pattern */ 760GrLineOption *lnp_option; /* width + dash pattern */ 761} GrLinePattern; 762 763All patterned line drawing functions take a pointer to this structure as their 764last argument. The list of available functions: 765 766void GrPatternedLine(int x1,int y1,int x2,int y2,GrLinePattern *lp); 767void GrPatternedBox(int x1,int y1,int x2,int y2,GrLinePattern *lp); 768void GrPatternedCircle(int xc,int yc,int r,GrLinePattern *lp); 769void GrPatternedEllipse(int xc,int yc,int xa,int ya,GrLinePattern *lp); 770void GrPatternedCircleArc(int xc,int yc,int r,int start,int end,GrLinePattern *lp); 771void GrPatternedEllipseArc(int xc,int yc,int xa,int ya,int start,int end,GrLinePattern *lp); 772void GrPatternedPolyLine(int numpts,int points[][2],GrLinePattern *lp); 773void GrPatternedPolygon(int numpts,int points[][2],GrLinePattern *lp); 774 775 776Text drawing 777 778The library supports loadable bit-mapped (i.e. not scalable!) fonts. 779Some of these fonts were converted from VGA BIOS fonts and fonts on utility 780diskettes coming with VGA cards. These fonts have all 256 characters. Some 781additional fonts were converted from fonts in the MIT X11 distribution. These 782have a variable number of characters, some support all 256 character codes, 783some only the printable ASCII codes. Fonts also have family names, which are 784used in a font lookup procedure supported by the library (see later). The 785following font families are included in the distribution: 786 787 788 789 790 791LIBGRX graphics library user's manual 16 792 793 794Font file name: Family: Description: 795 796pc<W>x<H>[t].fnt pc BIOS font, fixed 797xm<W>x<H>[b][i].fnt X_misc X11, fixed, miscellaneous group 798char<H>[b][i].fnt char X11, proportional, charter family 799cour<H>[b][i].fnt cour X11, fixed, courier 800helve<H>[b][i].fnt helve X11, proportional, helvetica 801lucb<H>[b][i].fnt lucb X11, proportional, lucida bright 802lucs<H>[b][i].fnt lucs X11, proportional, lucida sans serif 803luct<H>[b][i].fnt luct X11, fixed, lucida typewriter 804ncen<H>[b][i].fnt ncen X11, proportional, new century schoolbook 805symb<H>.fnt symbol X11, proportional, greek letters, 806symbols 807tms<H>[b][i].fnt times X11, proportional, times 808 809In the font names <W> means the font width, <H> the font height. Many font 810families have bold and/or italic variants. The files containing these fonts 811contain a 'b' and/or 'i' character in their name just before the extension. 812Additionally, the strings "_bold" and/or "_ital" are appended to the font 813family names. Some of the pc BIOS fonts come in thin formats also, these are 814denoted by a 't' in their file names and the string "_thin" in their family 815names. 816 817NOTE: the basic libgrx distribution ("cbgrx101.zip") contains only the full 818"pc", "courier", "helve", "symbol" and "times" font families and selected 819sizes from the "X_misc" family. (Because of archive size considerations!) The 820full compliment of fonts can be found in the archive file named 821"cbgrxfnt.zip", which should be available from the same site where the basic 822library was obtained from. 823 824Fonts are loaded with the 'GrLoadFont' function. If the font file name 825starts with any path separator character or character sequence ('<drive 826letter>:', '/' or '\') then it is loaded from the specified directory, 827otherwise the font is loaded from the default font path. The font path can be 828set up with the 'GrSetFontPath' function. If the font path is not set then the 829value of the 'GRXFONT' environment variable is used as the font path. If 830'GrLoadFont' is called again with the name of an already loaded font then it 831will return a pointer to the result of the first loading. The special font 832names "@:pc8x8.fnt", "@:pc8x14.fnt" and "@:pc8x16.fnt" will cause 'GrLoadFont' 833to load the font from the BIOS of the graphics card of the PC (provided that 834it has the desired font). Alternatively, 'GrLoadBIOSFont' can also be called 835to load a font which resides in the BIOS of the display adapter. (The 836difference is that 'GrLoadFont' will look at the disk as well if the BIOS does 837not have the font. For example: EGA-s don't have a 16 row font in their BIOS.) 838Both font loading routines return NULL if the font was not found. When not 839needed any more, fonts can be unloaded (i.e. the storage occupied by them 840freed) by calling 'GrUnloadFont'. The prototype declarations for these 841functions: 842 843GrFont *GrLoadFont(char *name); 844GrFont *GrLoadBIOSFont(char *name); 845 846 847 848 849 850LIBGRX graphics library user's manual 17 851 852 853void GrUnloadFont(GrFont *font); 854void GrSetFontPath(char *path); 855 856The 'GrFont' structure is actually a font header, the real font data is 857right next to this header in memory, but it is typically hidden from the 858application program. If needed, the include file "grxfont.h" can provide more 859details. The 'GrFont' structure: 860 861typedef struct { 862short fnt_width; /* width (average for proportional) */ 863short fnt_height; /* font height */ 864short fnt_minchar; /* lowest character code in font */ 865short fnt_maxchar; /* highest character code in font */ 866short fnt_isfixed; /* nonzero if fixed font */ 867short fnt_internal; /* nonzero if BIOS font */ 868short fnt_baseline; /* baseline from top of font */ 869short fnt_undwidth; /* underline width (at bottom) */ 870char fnt_name[GR_NAMEWIDTH]; /* font file name (w/o path) */ 871char fnt_family[GR_NAMEWIDTH]; /* font family name */ 872} GrFont; 873 874There is a function: 'GrFindBestFont' which returns the font which 875matches best a desired size. (Best match: not bigger, but as close as 876possible). The application can specify whether it wants 'GrFindBestFont' to 877find the best match using fonts in their original sizes only, or possibly 878enlarged (with the value of the 'magnify' argument -- 0: no, nonzero: yes). 879'GrFindBestFont' also takes a string argument which specifies the font family 880from which to select the font. The string can specify several family patterns 881separated by the ':' character. Each pattern can contain the '?' and '*' 882wildcard characters which work the usual way (in UNIX sense -- i.e. "X*ital" 883will match "X_misc_ital", but not "X_misc_bold"..). 884 885GrTextOption *GrFindBestFont(int width,int height,int magnify,char *family,GrTextOption *where); 886 887The 'GrTextOption' structure specifies how to draw a character string: 888 889typedef struct { 890GrFont *txo_font; /* font to be used */ 891int txo_xmag; /* X magnification */ 892int txo_ymag; /* Y magnification */ 893union { 894int v; /* color when no attributes */ 895GrColorTableP p; /* ptr to color table otherwise */ 896} txo_fgcolor,txo_bgcolor; /* foreground, background */ 897char txo_direct; /* direction */ 898char txo_xalign; /* X alignment */ 899char txo_yalign; /* Y alignment */ 900char txo_chrtype; /* character type */ 901} GrTextOption; 902 903 904 905 906 907LIBGRX graphics library user's manual 18 908 909 910The font can be enlarged independently in the X and Y directions, ('txo_xmag' 911and 'txo_ymag' slots -- values: 1 and up) the text can be rotated in 912increments of 90 degrees ('txo_direct'), alignments can be set in both 913directions ('txo_xalign' and 'txo_yalign'), and separate fore and background 914colors can be specified. The accepted text direction values: 915 916#define GR_TEXT_RIGHT 0 /* normal */ 917#define GR_TEXT_DOWN 1 /* downward */ 918#define GR_TEXT_LEFT 2 /* upside down, right to left */ 919#define GR_TEXT_UP 3 /* upward */ 920#define GR_TEXT_DEFAULT GR_TEXT_RIGHT 921 922The accepted horizontal and vertical alignment option values: 923 924#define GR_ALIGN_LEFT 0 /* X only */ 925#define GR_ALIGN_TOP 0 /* Y only */ 926#define GR_ALIGN_CENTER 1 /* X, Y */ 927#define GR_ALIGN_RIGHT 2 /* X only */ 928#define GR_ALIGN_BOTTOM 2 /* Y only */ 929#define GR_ALIGN_BASELINE 3 /* Y only */ 930#define GR_ALIGN_DEFAULT GR_ALIGN_LEFT 931 932Text strings can be of three different types: one character per byte (i.e. the 933usual C character string, this is the default), one character per 16-bit word 934(suitable for fonts with a large number of characters), and a PC-style 935character-attribute pair. In the last case the 'GrTextOption' structure must 936contain a pointer to a color table of size 16 (fg color bits in attrib) or 8 937(bg color bits). (The color table format is explained in more detail in the 938previous section explaining the methods to build fill patterns.) The supported 939text types: 940 941#define GR_BYTE_TEXT 0 /* one byte per character */ 942#define GR_WORD_TEXT 1 /* two bytes per character */ 943#define GR_ATTR_TEXT 2 /* char w/ PC style attribute byte */ 944 945The PC-style attribute text uses the same layout (first byte: character, 946second: attributes) and bitfields as the text mode screen on the PC. The only 947difference is that the 'blink' bit is not supported (it would be very time 948consuming -- the PC text mode does it with hardware support). This bit is used 949instead to control the underlined display of characters. For convenience the 950following attribute manipulation macros have been declared in "grx.h": 951 952#define GR_BUILD_ATTR(fgcolor,bgcolor,underline) \ 953((fgcolor) & 15) | (((bgcolor) & 7) << 4) | (((underline) & 1) << 7)) 954#define GR_ATTR_FGCOLOR(attr) ((attr) & 15) 955#define GR_ATTR_BGCOLOR(attr) (((attr) >> 4) & 7) 956#define GR_ATTR_UNDERLINE(attr) (((attr) >> 7) & 1) 957 958Text strings of the types 'GR_BYTE_TEXT' and 'GR_WORD_TEXT" can also be drawn 959underlined. This is controlled by OR-ing the constant 'GR_UNDERLINE_TEXT' to 960the foreground color value: 961 962 963 964 965 966LIBGRX graphics library user's manual 19 967 968 969#define GR_UNDERLINE_TEXT (GrXOR << 6) 970 971After the application initializes a text option structure with the 972desired values it can call one of the following two text drawing functions: 973 974void GrDrawChar(int chr,int x,int y,const GrTextOption *opt); 975void GrDrawString(char *text,int length,int x,int y,const GrTextOption *opt); 976 977NOTE: text drawing is fastest when the font is not magnified, it is drawn in 978the 'normal' direction, and the character does not have to be clipped. It this 979case the library can use the appropriate low-level video RAM access routine 980(see "INTERNAL.DOC" for more details), while in any other case the text is 981drawn pixel-by-pixel (or rectangle-by-rectangle if enlarged) by the 982higher-level code. 983 984The function 'GrTextXY' is provided for compatibility with the original 985256 color DJGPP graphics library. It draws the text in the standard direction, 986unmagnified, and using the 16 row BIOS font on VGA-s or the 14 row font on 987EGA-s. 988 989void GrTextXY(int x,int y,char *text,int fg,int bg); 990 991The size of a font, a character or a text string can be obtained by 992calling one of the following functions. These functions also take into 993consideration the magnification and text direction specified in the text 994option structure passed to them. 995 996int GrFontHeight(GrTextOption *opt); 997int GrFontWidth(GrTextOption *opt); 998int GrCharWidth(int chr,const GrTextOption *opt); 999int GrCharHeight(int chr,const GrTextOption *opt); 1000int GrStringWidth(char *text,int length,const GrTextOption *opt); 1001int GrStringHeight(char *text,int length,const GrTextOption *opt); 1002 1003The 'GrTextRegion' structure and its associated functions can be used to 1004implement a fast (as much as possible in graphics modes) rectangular text 1005window using a fixed font. Clipping for such windows is done in character size 1006increments instead of pixels (i.e. no partial characters are drawn). Only 1007fixed fonts can be used in their natural size. 'GrDumpText' will cache the 1008code of the drawn characters in the buffer pointed to by the 'backup' slot (if 1009it is non-NULL) and will draw a character only if the previously drawn 1010character in that grid element is different. This can speed up text scrolling 1011significantly in graphics modes. The supported text types are the same as 1012above. 1013 1014typedef struct { 1015GrFont *txr_font; /* font to be used */ 1016char *txr_buffer; /* pointer to text buffer */ 1017char *txr_backup; /* optional backup buffer */ 1018int txr_xpos; /* upper left corner X coordinate */ 1019int txr_ypos; /* upper left corner Y coordinate */ 1020 1021 1022 1023 1024 1025LIBGRX graphics library user's manual 20 1026 1027 1028int txr_width; /* width of area in chars */ 1029int txr_height; /* height of area in chars */ 1030int txr_lineoffset; /* offset in buffer(s) between lines */ 1031union { 1032int v; /* color when no attributes */ 1033GrColorTableP p; /* ptr to color table otherwise */ 1034} txr_fgcolor,txr_bgcolor; /* foreground, background */ 1035char txr_chrtype; /* character type (see above) */ 1036} GrTextRegion; 1037 1038void GrDumpChar(int chr,int col,int row,const GrTextRegion *r); 1039void GrDumpText(int col,int row,int wdt,int hgt,const GrTextRegion *r); 1040void GrDumpTextRegion(const GrTextRegion *r); 1041 1042The 'GrDumpTextRegion' function outputs the whole text region, while 1043'GrDumpText' draws only a user-specified part of it. 'GrDumpChar' updates the 1044character in the buffer at the specified location with the new character 1045passed to it as argument and then draws the new character on the screen as 1046well. 1047 1048 1049Drawing in user coordinates 1050 1051There is a second set of the graphics primitives which operates in user 1052coordinates. Every context has a user to screen coordinate mapping associated 1053with it. An application specifies the user window by calling the 1054'GrSetUserWindow' function. 1055 1056void GrSetUserWindow(int x1,int y1,int x2,int y2); 1057 1058A call to this function it in fact specifies the virtual coordinate limits 1059which will be mapped onto the current context regardless of the size of the 1060context. For example, the call: 1061 1062GrSetUserWindow(0,0,11999,8999); 1063 1064tells the library that the program will perform its drawing operations in a 1065coordinate system X:0...11999 (width = 12000) and Y:0...8999 (height = 9000). 1066This coordinate range will be mapped onto the total area of the current 1067context. The virtual coordinate system can also be shifted. For example: 1068 1069GrSetUserWindow(5000,2000,16999,10999); 1070 1071The user coordinates can even be used to turn the usual left-handed coordinate 1072system (0:0 corresponds to the upper left corner) to a right handed one (0:0 1073corresponds to the bottom left corner) by calling: 1074 1075GrSetUserWindow(0,8999,11999,0); 1076 1077 1078 1079 1080 1081LIBGRX graphics library user's manual 21 1082 1083 1084The library also provides three utility functions for the query of the 1085current user coordinate limits and for converting user coordinates to screen 1086coordinates and vice versa. 1087 1088void GrGetUserWindow(int *x1,int *y1,int *x2,int *y2); 1089void GrGetScreenCoord(int *x,int *y); 1090void GrGetUserCoord(int *x,int *y); 1091 1092If an application wants to take advantage of the user to screen 1093coordinate mapping it has to use the user coordinate version of 1094the graphics primitives. These have exactly the same parameter 1095passing conventions as their screen coordinate counterparts. 1096NOTE: the user coordinate system is not initialized by the 1097library! The application has to set up its coordinate mapping 1098before calling any of the use coordinate drawing functions -- 1099otherwise the program will almost certainly exit (in a quite 1100ungraceful fashion) with a 'division by zero' error. The list of 1101supported user coordinate drawing functions: 1102 1103void GrUsrPlot(int x,int y,int c); 1104void GrUsrLine(int x1,int y1,int x2,int y2,int c); 1105void GrUsrHLine(int x1,int x2,int y,int c); 1106void GrUsrVLine(int x,int y1,int y2,int c); 1107void GrUsrBox(int x1,int y1,int x2,int y2,int c); 1108void GrUsrFilledBox(int x1,int y1,int x2,int y2,int c); 1109void GrUsrFramedBox(int x1,int y1,int x2,int y2,int wdt,GrFBoxColors *c); 1110void GrUsrCircle(int xc,int yc,int r,int c); 1111void GrUsrEllipse(int xc,int yc,int xa,int ya,int c); 1112void GrUsrCircleArc(int xc,int yc,int r,int start,int end,int c); 1113void GrUsrEllipseArc(int xc,int yc,int xa,int ya,int start,int end,int c); 1114void GrUsrFilledCircle(int xc,int yc,int r,int c); 1115void GrUsrFilledEllipse(int xc,int yc,int xa,int ya,int c); 1116void GrUsrFilledCircleArc(int xc,int yc,int r,int start,int end,int c); 1117void GrUsrFilledEllipseArc(int xc,int yc,int xa,int ya,int start,int end,int c); 1118void GrUsrPolyLine(int numpts,int points[][2],int c); 1119void GrUsrPolygon(int numpts,int points[][2],int c); 1120void GrUsrFilledConvexPolygon(int numpts,int points[][2],int c); 1121void GrUsrFilledPolygon(int numpts,int points[][2],int c); 1122int GrUsrPixel(int x,int y); 1123 1124void GrUsrCustomLine(int x1,int y1,int x2,int y2,const GrLineOption *o); 1125void GrUsrCustomBox(int x1,int y1,int x2,int y2,const GrLineOption *o); 1126void GrUsrCustomCircle(int xc,int yc,int r,const GrLineOption *o); 1127void GrUsrCustomEllipse(int xc,int yc,int xa,int ya,const GrLineOption *o); 1128void GrUsrCustomCircleArc(int xc,int yc,int r,int start,int end,const GrLineOption *o); 1129void GrUsrCustomEllipseArc(int xc,int yc,int xa,int ya,int start,int end,const GrLineOption *o); 1130void GrUsrCustomPolyLine(int numpts,int points[][2],const GrLineOption *o); 1131void GrUsrCustomPolygon(int numpts,int points[][2],const GrLineOption *o); 1132 1133void GrUsrPatternedPlot(int x,int y,GrPattern *p); 1134void GrUsrPatternedLine(int x1,int y1,int x2,int y2,GrLinePattern *lp); 1135 1136 1137 1138 1139 1140LIBGRX graphics library user's manual 22 1141 1142 1143void GrUsrPatternedBox(int x1,int y1,int x2,int y2,GrLinePattern *lp); 1144void GrUsrPatternedCircle(int xc,int yc,int r,GrLinePattern *lp); 1145void GrUsrPatternedEllipse(int xc,int yc,int xa,int ya,GrLinePattern *lp); 1146void GrUsrPatternedCircleArc(int xc,int yc,int r,int start,int end,GrLinePattern *lp); 1147void GrUsrPatternedEllipseArc(int xc,int yc,int xa,int ya,int start,int end,GrLinePattern *lp); 1148void GrUsrPatternedPolyLine(int numpts,int points[][2],GrLinePattern *lp); 1149void GrUsrPatternedPolygon(int numpts,int points[][2],GrLinePattern *lp); 1150 1151void GrUsrPatternFilledBox(int x1,int y1,int x2,int y2,GrPattern *p); 1152void GrUsrPatternFilledCircle(int xc,int yc,int r,GrPattern *p); 1153void GrUsrPatternFilledEllipse(int xc,int yc,int xa,int ya,GrPattern *p); 1154void GrUsrPatternFilledCircleArc(int xc,int yc,int r,int start,int end,GrPattern *p); 1155void GrUsrPatternFilledEllipseArc(int xc,int yc,int xa,int ya,int start,int end,GrPattern *p); 1156void GrUsrPatternFilledConvexPolygon(int numpts,int points[][2],GrPattern *p); 1157void GrUsrPatternFilledPolygon(int numpts,int points[][2],GrPattern *p); 1158 1159GrTextOption *GrUsrFindBestFont(int width,int height,int magnify,char *family,GrTextOption *where); 1160void GrUsrDrawChar(int chr,int x,int y,const GrTextOption *opt); 1161void GrUsrDrawString(char *text,int length,int x,int y,const GrTextOption *opt); 1162void GrUsrTextXY(int x,int y,char *text,int fg,int bg); 1163 1164 1165Graphics cursors 1166 1167The library provides support for the creation and usage of an unlimited 1168number of graphics cursors. An application can use these cursors for any 1169purpose. Cursors always save the area they occupy before they are drawn. When 1170moved or erased they restore this area. As a general rule of thumb, an 1171application should erase a cursor before making changes to an area it occupies 1172and redraw the cursor after finishing the drawing. All cursor and mouse 1173related declaration are in the include file "mousex.h". Cursors are created 1174with the 'GrBuildCursor' function: 1175 1176GrCursor *GrBuildCursor(char *data,int w,int h,int xo,int yo,const GrColorTableP c); 1177 1178The 'data', 'w' (=width), 'h' (=height) and 'c' (= color table) arguments are 1179similar to the arguments of the pixmap building library function: 1180'GrBuildPixmap'. (See that paragraph for a more detailed explanation.) The 1181only difference is that the pixmap data is interpreted slightly differently: 1182any pixel with value zero is taken as a "transparent" pixel, i.e. the 1183background will show through the cursor pattern at that pixel. A pixmap data 1184byte with value = 1 will refer to the first color in the table, and so on. The 1185'xo' (= X offset) and 'yo' (= Y offset) arguments specify the position (from 1186the top left corner of the cursor pattern) of the cursor's "hot point". The 1187'GrCursor' data structure: 1188 1189 1190 1191 1192 1193LIBGRX graphics library user's manual 23 1194 1195 1196typedef struct { 1197GrVidRAM cr_andmask; /* cursor bitmap to AND */ 1198GrVidRAM cr_ormask; /* cursor bitmap to OR */ 1199GrVidRAM cr_work; /* work area */ 1200GrVidRAM cr_save; /* screen save area */ 1201int cr_xcord,cr_ycord; /* cursor position on screen */ 1202int cr_xsize,cr_ysize; /* cursor size */ 1203int cr_xoffs,cr_yoffs; /* LU corner to hot point offset */ 1204int cr_xwork,cr_ywork; /* save/work area sizes */ 1205int cr_xwpos,cr_ywpos; /* save/work area position on screen */ 1206int cr_displayed; /* set if displayed */ 1207} GrCursor; 1208 1209is typically not used (i.e. read or changed) by the application program, it 1210should just pass pointers to these structures to the appropriate library 1211functions. Other cursor manipulation functions: 1212 1213void GrDestroyCursor(GrCursor *cursor); 1214void GrDisplayCursor(GrCursor *cursor); 1215void GrEraseCursor(GrCursor *cursor); 1216void GrMoveCursor(GrCursor *cursor,int x,int y); 1217 1218 1219Mouse event handling 1220 1221All mouse services need the presence of a mouse and an installed 1222Microsoft compatible mouse driver. An application can test whether a mouse is 1223available by calling the function: 1224 1225int MouseDetect(void); 1226 1227which will return zero if no mouse (or mouse driver) is present, non-zero 1228otherwise. If the mouse is present the application may decide if it wants to 1229use the mouse in interrupt-driven or polled mode. The polled mode is 1230compatible with previous releases of DJGPP and the 256 color graphics library, 1231it uses the mouse driver interrupts (INT 33h) to query the mouse about its 1232position and buttons. This method is adequate if the program can do the 1233polling in a tight enough loop. If the program does lengthy computations in 1234the background during which a "frozen" mouse and the loss of mouse button 1235presses would be disturbing it has to use the interrupt driven method. For 1236this a patched version of GO32 is needed -- a GO32 version dated after the 1237middle of April 1992 should work. The interrupt driven mouse event mechanism 1238uses an event queue library (described in the document "EVENTS.DOC") which 1239stores all user interaction events (mouse presses and keyboard hits) in a 1240queue, timestamped, in the order of occurrence. The disadvantage of the 1241interrupt-driven mouse event mechanism is that it may be harder to debug. To 1242select between the two modes the following function needs to be called: 1243 1244void MouseEventMode(int use_interrupts); 1245 1246 1247 1248 1249 1250LIBGRX graphics library user's manual 24 1251 1252 1253If the 'use_interrupts' parameter is zero the mouse is put into polled mode 1254(this is the default), otherwise it will work interrupt-driven. After 1255selecting the mode, the mouse can be initialized by calling: 1256 1257void MouseInit(void); 1258 1259It is not necessary to call this function as the first call the 1260'MouseGetEvent' (see later) function will also perform the initialization. 1261However, if the mouse event mode is changed after using 'MouseGetEvent', a 1262call to 'MouseInit' is the only way to enforce the change. 1263 1264If the mouse is used in interrupt-driven mode, it is a good practice to 1265call 'MouseUnInit' before exiting the program. This will restore any interrupt 1266vectors hooked by the program to their original values. 1267 1268void MouseUnInit(void); 1269 1270The mouse can be controlled with the following functions: 1271 1272void MouseSetSpeed(int speed); 1273void MouseSetAccel(int thresh,int accel); 1274void MouseSetLimits(int x1,int y1,int x2,int y2); 1275void MouseGetLimits(int *x1,int *y1,int *x2,int *y2); 1276void MouseWarp(int x,int y); 1277 1278The library calculates the mouse position only from the mouse mickey counters. 1279(To avoid the limit and 'rounding to the next multiple of eight' problem with 1280the Microsoft mouse driver when it finds itself in a graphics mode unknown to 1281it.) The 'speed' parameter to the 'MouseSetSpeed' function is used as a 1282divisor, i.e. coordinate changes are obtained by dividing the mickey counter 1283changes by this value. In high resolution graphics modes the value of one just 1284works fine, in low resolution modes (320x200 or similar) it is best set the 1285speed to two or three. (Of course, it also depends on the sensitivity the 1286mouse.) The 'MouseSetAccel' function is used to control the ballistic effect: 1287if a mouse coordinate changes between two samplings by more than the 'thresh' 1288parameter, the change is multiplied by the 'accel' parameter. NOTE: some mouse 1289drivers perform similar calculations before reporting the coordinates in 1290mickeys. In this case the acceleration done by the library will be additional 1291to the one already performed by the mouse driver. The limits of the mouse 1292movement can be set (passed limits will be clipped to the screen) with 1293'MouseSetLimits' (default is the whole screen) and the current limits can be 1294obtained with 'MouseGetLimits'. 'MouseWarp' sets the mouse cursor to the 1295specified position. 1296 1297As typical mouse drivers do not know how to draw mouse cursors in high 1298resolution graphics modes, the mouse cursor is drawn by the library. The mouse 1299cursor can be set with: 1300 1301void MouseSetCursor(GrCursor *cursor); 1302void MouseSetColors(int fg,int bg); 1303 1304 1305 1306 1307 1308LIBGRX graphics library user's manual 25 1309 1310 1311'MouseSetColors' uses an internal arrow pattern, the color 'fg' will be used 1312as the interior of it and 'bg' will be the border. The current mouse cursor 1313can be obtained with: 1314 1315GrCursor *MouseGetCursor(void); 1316 1317The mouse cursor can be displayed/erased with: 1318 1319void MouseDisplayCursor(void); 1320void MouseEraseCursor(void); 1321 1322The mouse cursor can be left permanently displayed. All graphics primitives 1323except for the few non-clipping functions check for conflicts with the mouse 1324cursor and erase it before the drawing if necessary. Of course, it may be more 1325efficient to erase the cursor manually before a long drawing sequence and 1326redraw it after completion. The library provides an alternative pair of calls 1327for this purpose which will erase the cursor only if it interferes with the 1328drawing: 1329 1330int MouseBlock(GrContext *c,int x1,int y1,int x2,int y2); 1331void MouseUnBlock(void); 1332 1333'MouseBlock' should be passed the context in which the drawing will take place 1334(the usual convention of NULL meaning the current context is supported) and 1335the limits of the affected area. It will erase the cursor only if it 1336interferes with the drawing. If it returns a non-zero value then 1337'MouseUnBlock' has to be called at the end of the drawing, otherwise it should 1338not be called. 1339 1340The library supports (beside the simple cursor drawing) three types of 1341"rubberband" attached to the mouse cursor. The 'MouseSetCursorMode' function 1342is used to select the cursor drawing mode. 1343 1344void MouseSetCursorMode(int mode,...); 1345 1346The parameter 'mode' can have the following values: 1347 1348/* 1349* MOUSE CURSOR modes: 1350* M_CUR_NORMAL -- just the cursor 1351* M_CUR_RUBBER -- rectangular rubber band (XOR-d to the screen) 1352* M_CUR_LINE -- line attached to the cursor 1353* M_CUR_BOX -- rectangular box dragged by the cursor 1354*/ 1355#define M_CUR_NORMAL 0 1356#define M_CUR_RUBBER 1 1357#define M_CUR_LINE 2 1358#define M_CUR_BOX 3 1359 1360'MouseSetCursorMode' takes different parameters depending on the cursor 1361drawing mode selected. The accepted call formats are: 1362 1363 1364 1365 1366 1367LIBGRX graphics library user's manual 26 1368 1369 1370MouseSetCursorMode(M_CUR_NORMAL); 1371MouseSetCursorMode(M_CUR_RUBBER,xanchor,yanchor,color); 1372MouseSetCursorMode(M_CUR_LINE,xanchor,yanchor,color); 1373MouseSetCursorMode(M_CUR_BOX,dx1,dy1,dx2,dy2,color); 1374 1375The anchor parameters for the rubberband and rubberline modes specify a fixed 1376screen location to which the other corner of the primitive is bound. The 'dx1' 1377through 'dy2' parameters define the offsets of the corners of the dragged box 1378from the hotpoint of the mouse cursor. The color value passed is always XOR-ed 1379to the screen, i.e. if an application wants the rubberband to appear in a 1380given color on a given background then it has to pass the XOR of these two 1381colors to 'MouseSetCursorMode'. 1382 1383The status of the mouse cursor can be obtained with calling 1384'MouseCursorIsDisplayed'. This function will return non-zero if the cursor is 1385displayed, zero if it is erased. 1386 1387int MouseCursorIsDisplayed(void); 1388 1389The 'MouseGetEvent' function is used to obtain the next mouse or 1390keyboard event. It takes a flag with various bits encoding the type of event 1391needed. It returns the event in a 'MouseEvent' structure. The relevant 1392declarations from "mousex.h": 1393 1394void MouseGetEvent(int flags,MouseEvent *event); 1395 1396typedef struct { 1397int flags; /* flags (see above) */ 1398int x,y; /* coordinates */ 1399int buttons; /* button state */ 1400int key; /* key code from keyboard */ 1401int kbstat; /* keybd status (ALT, CTRL, etc..) */ 1402long time; /* time stamp of the event */ 1403} MouseEvent; 1404 1405The event structure has been extended with a keyboard status word (thus a 1406program can check for combinations like ALT-<left mousebutton press>) and a 1407time stamp (in DOS clock ticks since the start of the program) which can be 1408used to check for double clicks, etc... The following macros have been defined 1409in "mousex.h" to help in creating the control flag for 'MouseGetEvent' and 1410decoding the various bits in the event structure: 1411 1412/* 1413* MOUSE event flag bits 1414*/ 1415#define M_MOTION 0x001 1416#define M_LEFT_DOWN 0x002 1417#define M_LEFT_UP 0x004 1418#define M_RIGHT_DOWN 0x008 1419#define M_RIGHT_UP 0x010 1420#define M_MIDDLE_DOWN 0x020 1421 1422 1423 1424 1425 1426LIBGRX graphics library user's manual 27 1427 1428 1429#define M_MIDDLE_UP 0x040 1430#define M_BUTTON_DOWN (M_LEFT_DOWN | M_MIDDLE_DOWN | M_RIGHT_DOWN) 1431#define M_BUTTON_UP (M_LEFT_UP | M_MIDDLE_UP | M_RIGHT_UP) 1432#define M_BUTTON_CHANGE (M_BUTTON_UP | M_BUTTON_DOWN ) 1433 1434/* 1435* MOUSE button status bits 1436*/ 1437#define M_LEFT 1 1438#define M_RIGHT 2 1439#define M_MIDDLE 4 1440 1441/* 1442* Other bits and combinations 1443*/ 1444#define M_KEYPRESS 0x080 /* keypress */ 1445#define M_POLL 0x100 /* do not wait for the event */ 1446#define M_NOPAINT 0x200 1447#define M_EVENT (M_MOTION | M_KEYPRESS | M_BUTTON_DOWN | M_BUTTON_UP) 1448 1449/* 1450* KEYBOARD status word bits 1451*/ 1452#define KB_RIGHTSHIFT 0x01 /* right shift key depressed */ 1453#define KB_LEFTSHIFT 0x02 /* left shift key depressed */ 1454#define KB_CTRL 0x04 /* CTRL depressed */ 1455#define KB_ALT 0x08 /* ALT depressed */ 1456#define KB_SCROLLOCK 0x10 /* SCROLL LOCK active */ 1457#define KB_NUMLOCK 0x20 /* NUM LOCK active */ 1458#define KB_CAPSLOCK 0x40 /* CAPS LOCK active */ 1459#define KB_INSERT 0x80 /* INSERT state active */ 1460 1461#define KB_SHIFT (KB_LEFTSHIFT | KB_RIGHTSHIFT) 1462 1463'MouseGetEvent' will display the mouse cursor if it was previously erased and 1464the 'M_NOPAINT' bit is not set in the flag passed to it. In this case it will 1465also erase the cursor after an event has been obtained. 1466 1467NOTE: some of the mouse event constants have different values than in the 1468original DJGPP graphics library. This change was necessary to better follow 1469the mouse driver conventions for assigning bits with similar functions. 1470 1471The generation of mouse and keyboard events can be individually enabled or 1472disabled (by passing a non-zero or zero, respectively, value in the 1473corresponding 'enable_XX' parameter) by calling: 1474 1475void MouseEventEnable(int enable_kb,int enable_ms); 1476 1477 1478README for GRX 1.03 beta release 1479================================ 1480 1481This is file README.GRX. It can be found at the beta7 distribution site 1482and also in the DOCS sub-directory of the GRX archive. This file contains 1483additional information about the new graphics-related features of GO32, 1484the new graphics drivers and GRX 1.03. 1485 1486What is in this release? 1487------------------------ 1488 1489This is an intermediate release based on my working sources. This version 1490does not yet work with DPMI. On the other hand, it has been modified to work 1491with the new (.VDR) drivers. These drivers together with the modifications 1492in GO32 1.11 allow the use of more than 1MB of video RAM. Virtual screens 1493larger than the displayed screen are also supported, together with a GO32 1494function to change the start of the displayed region (pan). The beta GO32 14951.11 already has a new format built-in VESA driver. 1496 1497This version only supports display modes which were present in GRX 1.02. 1498(I.e. 16, 256, 32K colors and accelerated S3/8514A 256 color modes.) I don't 1499intend to finish the missing display modes in the current page-fault based 1500video RAM access mode. Currently I am working on a new set of low-level GRX 1501video RAM access routines which will use explicit paging. These will support 1502DPMI graphics with >64K frame buffers. As soon as these are finished and 1503tested there will be another GRX release. 1504 1505The other new feature of this release is that all thick and patterned 1506line primitives (which were missing from GRX 1.02) are present in this 1507version. 1508 1509New driver interface 1510-------------------- 1511 1512The format of the VDR drivers can be found in the "grdriver.h" file in 1513the GO32 source directory or in the NDRIVERS directory of the GRX archive. 1514The built-in driver in GO32 should work with any VESA compatible SVGA card. 1515Older (.GRD or .GRN) drivers still work with the new GO32 and graphics 1516library. There is a small change in the driver specification part of the 1517GO32 environment variable: 1518 1519SET GO32=driver <driver_name>::<driver_options> tw ... 1520 ^^^^^^^^^^^^^^^^^^ 1521 new fields 1522 1523If the name of the driver is followed by two colons and a string then this 1524string is taken as an option string for the driver. GO32 configures the driver 1525according to the characters in this string when the driver is loaded. (Which 1526now happens only when the driver is first used.) The option string is 1527ignored for .GRD and .GRD drivers. 1528 1529The option string can contain the following characters (in any order, case 1530does not matter): 1531 1532p: Enables protected mode paging. For .VDR drivers the default is to use 1533 the driver's paging function in real mode. This is necessary because 1534 the VESA BIOS paging function was written for real mode. However, many 1535 VESA BIOS-es are well written, and their paging function can be used 1536 in protected mode. Give it a try, if it fails then you have to use 1537 real mode paging which is MUCH slower. (paging with .GRD and .GRN 1538 drivers is always in protected mode) 1539 1540f: Enables fast 256 color mode. On some SVGA cards the planar, mode X-like 1541 256 color memory organization can be used even in SVGA modes. There are 1542 a few operations (especially horizontal scan line fills) which can 1543 be much faster in this mode. Give it a try -- and if you see garbage 1544 on the screen then it does not work with your card. 1545 15465: This field is necessary only if your VESA BIOS is version 1.1 or older 1547 and the 64K (16 bit) color mode reported by it is really only a 32K 1548 (15 bit) mode. You can find out your VESA version number and a lot of 1549 other VESA related stuff by running the VESAINFO program in the 1550 NDRIVERS directory of the GRX archive. 1551 1552If you want to use the built-in GO32 driver with options use the following 1553syntax: 1554 1555 SET GO32 = driver ::pf5 tw ... 1556 1557When using a new .VDR driver with GO32 1.11 the video memory is mapped as 1558follows: 1559 1560 0xd0000000 .. 0xd0100000 old 1MB RW area 1561 0xd0100000 .. 0xd0200000 old 1MB R0 area 1562 0xd0200000 .. 0xd0300000 old 1MB W0 area 1563 1564 0xd1000000 .. 0xd2000000 new 16MB RW area 1565 0xd2000000 .. 0xd3000000 new 16MB R0 area 1566 0xd3000000 .. 0xd4000000 new 16MB W0 area 1567 1568GRX 1.03 uses the 1MB areas whenever the frame buffer is less then 1MB, 1569otherwise it uses the 16MB areas. 1570 1571GO32 1.11 supports the following new int 0x10 calls: 1572 1573Mode set with virtual screen sizes: 1574Input: 1575ax = 10 // = GR_custom_graphics 1576bx = colors 1577cx = desired screen width 1578dx = desired screen height 1579VDR_driver_header.virtual_x = desired virtual width 1580VDR_driver_header.virtual_y = desired virtual heigth 1581Output: 1582bx = mode descriptor bits 1583cx = actual screen width 1584dx = actual screen height 1585VDR_driver_header.virtual_x = actual virtual width 1586VDR_driver_header.virtual_y = actual virtual heigth 1587 1588Inquire driver header linear address: 1589Input: 1590ax = 0xfffe 1591Output: 1592eax = linear address of driver header in real memory. (Add 0xe0000000 1593 when used in non-DPMI modes of the extender). Use this buffer 1594 for passing the virtual screen parameters to the driver. 1595 1596Call driver paging function in real mode: 1597Input: 1598ax = 0xfffd 1599bl = read page 1600bh = write page 1601Output: none 1602 1603Set displayed screen start when virtual screen > displayed screen 1604Input: 1605ax = 0xfffc 1606cx = X position 1607dx = Y position 1608Output: none 1609 1610 1611