362 lines
11 KiB
C
362 lines
11 KiB
C
#include "grobjs.h"
|
|
#include "grdevice.h"
|
|
#include <stdlib.h>
|
|
|
|
grDeviceChain gr_device_chain[ GR_MAX_DEVICES ];
|
|
int gr_num_devices = 0;
|
|
|
|
static
|
|
grDevice* find_device( const char* device_name )
|
|
{
|
|
int index = 0;
|
|
|
|
if (device_name)
|
|
{
|
|
for ( index = gr_num_devices-1; index > 0; index-- )
|
|
if ( strcmp( device_name, gr_device_chain[index].name ) == 0 )
|
|
break;
|
|
}
|
|
|
|
if ( index < 0 || gr_num_devices <= 0 || !gr_device_chain[index].device )
|
|
{
|
|
grError = gr_err_invalid_device;
|
|
return 0;
|
|
}
|
|
|
|
return gr_device_chain[index].device;
|
|
}
|
|
|
|
|
|
|
|
/**********************************************************************
|
|
*
|
|
* <Function>
|
|
* grGetDeviceModes
|
|
*
|
|
* <Description>
|
|
* queries the available pixel modes for a device.
|
|
*
|
|
* <Input>
|
|
* device_name :: name of device to be used. 0 for the default
|
|
* device. For a list of available devices, see
|
|
* grInitDevices.
|
|
*
|
|
* <Output>
|
|
* num_modes :: number of available modes. 0 in case of error,
|
|
* which really is an invalid device name.
|
|
*
|
|
* pixel_modes :: array of available pixel modes for this device
|
|
* this table is internal to the device and should
|
|
* not be freed by client applications.
|
|
*
|
|
* <Return>
|
|
* error code. 0 means success. invalid device name otherwise
|
|
*
|
|
* <Note>
|
|
* All drivers are _required_ to support at least the following
|
|
* pixel formats :
|
|
*
|
|
* - gr_pixel_mode_mono : i.e. monochrome bitmaps
|
|
* - gr_pixel_mode_gray : with any number of gray levels between
|
|
* 2 and 256.
|
|
*
|
|
* the pixel modes do not provide the number of grays in the case
|
|
* of "gray" devices. You should try to create a surface with the
|
|
* maximal number (256, that is) and see the value returned in
|
|
* the bitmap descriptor.
|
|
*
|
|
**********************************************************************/
|
|
|
|
extern void grGetDeviceModes( const char* device_name,
|
|
int *num_modes,
|
|
grPixelMode* *pixel_modes )
|
|
{
|
|
grDevice* device;
|
|
|
|
*num_modes = 0;
|
|
*pixel_modes = 0;
|
|
|
|
device = find_device( device_name );
|
|
if (device)
|
|
{
|
|
*num_modes = device->num_pixel_modes;
|
|
*pixel_modes = device->pixel_modes;
|
|
}
|
|
}
|
|
|
|
|
|
/**********************************************************************
|
|
*
|
|
* <Function>
|
|
* grNewSurface
|
|
*
|
|
* <Description>
|
|
* creates a new device-specific surface. A surface is either
|
|
* a window or a screen, depending on the device.
|
|
*
|
|
* <Input>
|
|
* device :: name of the device to use. A value of NULL means
|
|
* the default device (which depends on the system).
|
|
* for a list of available devices, see grInitDevices.
|
|
*
|
|
* <InOut>
|
|
* bitmap :: handle to a bitmap descriptor containing the
|
|
* requested pixel mode, number of grays and dimensions
|
|
* for the surface. the bitmap's 'pitch' and 'buffer'
|
|
* fields are ignored on input.
|
|
*
|
|
* On output, the bitmap describes the surface's image
|
|
* completely. It is possible to write directly in it
|
|
* with grBlitGlyphToBitmap, even though the use of
|
|
* grBlitGlyphToSurface is recommended.
|
|
*
|
|
* <Return>
|
|
* handle to the corresponding surface object. 0 in case of error
|
|
*
|
|
* <Note>
|
|
* All drivers are _required_ to support at least the following
|
|
* pixel formats :
|
|
*
|
|
* - gr_pixel_mode_mono : i.e. monochrome bitmaps
|
|
* - gr_pixel_mode_gray : with any number of gray levels between
|
|
* 2 and 256.
|
|
*
|
|
* This function might change the bitmap descriptor's fields. For
|
|
* example, when displaying a full-screen surface, the bitmap's
|
|
* dimensions will be set to those of the screen (e.g. 640x480
|
|
* or 800x600); also, the bitmap's 'buffer' field might point to
|
|
* the Video Ram depending on the mode requested..
|
|
*
|
|
* The surface contains a copy of the returned bitmap descriptor,
|
|
* you can thus discard the 'bitmap' parameter after the call.
|
|
*
|
|
**********************************************************************/
|
|
|
|
extern grSurface* grNewSurface( const char* device_name,
|
|
grBitmap* bitmap )
|
|
{
|
|
grDevice* device;
|
|
grSurface* surface;
|
|
|
|
/* Now find the device */
|
|
device = find_device( device_name );
|
|
if (!device) return 0;
|
|
|
|
surface = (grSurface*)grAlloc( device->surface_objsize );
|
|
if (!surface) return 0;
|
|
|
|
if ( !device->init_surface( surface, bitmap ) )
|
|
{
|
|
grFree( surface );
|
|
surface = 0;
|
|
}
|
|
return surface;
|
|
}
|
|
|
|
|
|
/**********************************************************************
|
|
*
|
|
* <Function>
|
|
* grRefreshRectangle
|
|
*
|
|
* <Description>
|
|
* this function is used to indicate that a given surface rectangle
|
|
* was modified and thus needs re-painting. It really is useful for
|
|
* windowed or gray surfaces.
|
|
*
|
|
* <Input>
|
|
* surface :: handle to target surface
|
|
* x :: x coordinate of the top-left corner of the rectangle
|
|
* y :: y coordinate of the top-left corner of the rectangle
|
|
* width :: rectangle width in pixels
|
|
* height :: rectangle height in pixels
|
|
*
|
|
**********************************************************************/
|
|
|
|
extern void grRefreshRectangle( grSurface* surface,
|
|
grPos x,
|
|
grPos y,
|
|
grPos width,
|
|
grPos height )
|
|
{
|
|
if (surface->refresh_rect)
|
|
surface->refresh_rect( surface, x, y, width, height );
|
|
}
|
|
|
|
|
|
|
|
/**********************************************************************
|
|
*
|
|
* <Function>
|
|
* grWriteSurfaceChar
|
|
*
|
|
* <Description>
|
|
* This function is equivalent to calling grWriteCellChar on the
|
|
* surface's bitmap, then invoking grRefreshRectangle.
|
|
*
|
|
* The graphics sub-system contains an internal Latin1 8x8 font
|
|
* which can be used to display simple strings of text without
|
|
* using FreeType.
|
|
*
|
|
* This function writes a single 8x8 character on the target bitmap.
|
|
*
|
|
* <Input>
|
|
* target :: handle to target surface
|
|
* x :: x pixel position of character cell's top left corner
|
|
* y :: y pixel position of character cell's top left corner
|
|
* charcode :: Latin-1 character code
|
|
* color :: color to be used to draw the character
|
|
*
|
|
**********************************************************************/
|
|
|
|
extern
|
|
void grWriteSurfaceChar( grSurface* target,
|
|
int x,
|
|
int y,
|
|
int charcode,
|
|
grColor color )
|
|
{
|
|
grWriteCellChar( &target->bitmap, x, y, charcode, color );
|
|
if (target->refresh_rect)
|
|
target->refresh_rect( target, x, y, 8, 8 );
|
|
}
|
|
|
|
|
|
/**********************************************************************
|
|
*
|
|
* <Function>
|
|
* grWriteSurfaceString
|
|
*
|
|
* <Description>
|
|
* This function is equivalent to calling grWriteCellString on the
|
|
* surface's bitmap, then invoking grRefreshRectangle.
|
|
*
|
|
* The graphics sub-system contains an internal Latin1 8x8 font
|
|
* which can be used to display simple strings of text without
|
|
* using FreeType.
|
|
*
|
|
* This function writes a string with the internal font
|
|
*
|
|
* <Input>
|
|
* target :: handle to target bitmap
|
|
* x :: x pixel position of string's top left corner
|
|
* y :: y pixel position of string's top left corner
|
|
* string :: Latin-1 text string
|
|
* color :: color to be used to draw the character
|
|
*
|
|
**********************************************************************/
|
|
|
|
extern
|
|
void grWriteSurfaceString( grSurface* target,
|
|
int x,
|
|
int y,
|
|
const char* string,
|
|
grColor color )
|
|
{
|
|
int len;
|
|
|
|
len = strlen(string);
|
|
grWriteCellString( &target->bitmap, x, y, string, color );
|
|
if (target->refresh_rect)
|
|
target->refresh_rect( target, x, y, 8*len, 8 );
|
|
}
|
|
|
|
|
|
/**********************************************************************
|
|
*
|
|
* <Function>
|
|
* grRefreshSurface
|
|
*
|
|
* <Description>
|
|
* a variation of grRefreshRectangle which repaints the whole surface
|
|
* to the screen.
|
|
*
|
|
* <Input>
|
|
* surface :: handle to target surface
|
|
*
|
|
**********************************************************************/
|
|
|
|
extern void grRefreshSurface( grSurface* surface )
|
|
{
|
|
if (surface->refresh_rect)
|
|
surface->refresh_rect( surface, 0, 0,
|
|
surface->bitmap.width,
|
|
surface->bitmap.rows );
|
|
}
|
|
|
|
|
|
|
|
/**********************************************************************
|
|
*
|
|
* <Function>
|
|
* grSetTitle
|
|
*
|
|
* <Description>
|
|
* set the window title of a given windowed surface.
|
|
*
|
|
* <Input>
|
|
* surface :: handle to target surface
|
|
* title_string :: the new title
|
|
*
|
|
**********************************************************************/
|
|
|
|
extern void grSetTitle( grSurface* surface,
|
|
const char* title_string )
|
|
{
|
|
if (surface->set_title)
|
|
surface->set_title( surface, title_string );
|
|
}
|
|
|
|
|
|
|
|
|
|
/**********************************************************************
|
|
*
|
|
* <Function>
|
|
* grListenSurface
|
|
*
|
|
* <Description>
|
|
* listen the events for a given surface
|
|
*
|
|
* <Input>
|
|
* surface :: handle to target surface
|
|
* event_mask :: the event mask (mode)
|
|
*
|
|
* <Output>
|
|
* event :: the returned event
|
|
*
|
|
* <Note>
|
|
* XXX : For now, only keypresses are supported.
|
|
*
|
|
**********************************************************************/
|
|
|
|
extern
|
|
int grListenSurface( grSurface* surface,
|
|
int event_mask,
|
|
grEvent *event )
|
|
{
|
|
return surface->listen_event( surface, event_mask, event );
|
|
}
|
|
|
|
|
|
#if 0
|
|
static
|
|
void gr_done_surface( grSurface* surface )
|
|
{
|
|
if (surface)
|
|
{
|
|
/* first of all, call the device-specific destructor */
|
|
surface->done(surface);
|
|
|
|
/* then remove the bitmap if we're owner */
|
|
if (surface->owner)
|
|
grFree( surface->bitmap.buffer );
|
|
|
|
surface->owner = 0;
|
|
surface->bitmap.buffer = 0;
|
|
grFree( surface );
|
|
}
|
|
}
|
|
#endif
|
|
|