#include "grobjs.h" #include "grdevice.h" #include #include 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; } /********************************************************************** * * * grGetDeviceModes * * * queries the available pixel modes for a device. * * * device_name :: name of device to be used. 0 for the default * device. For a list of available devices, see * grInitDevices. * * * 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. * * * error code. 0 means success. invalid device name otherwise * * * 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; } } /********************************************************************** * * * grNewSurface * * * creates a new device-specific surface. A surface is either * a window or a screen, depending on the device. * * * 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. * * * 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. * * * handle to the corresponding surface object. 0 in case of error * * * 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; } /********************************************************************** * * * grRefreshRectangle * * * 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. * * * 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 ); } /********************************************************************** * * * grWriteSurfaceChar * * * 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. * * * 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 ); } /********************************************************************** * * * grWriteSurfaceString * * * 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 * * * 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 ); } /********************************************************************** * * * grRefreshSurface * * * a variation of grRefreshRectangle which repaints the whole surface * to the screen. * * * 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 ); } /********************************************************************** * * * grSetTitle * * * set the window title of a given windowed surface. * * * 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 ); } /********************************************************************** * * * grListenSurface * * * listen the events for a given surface * * * surface :: handle to target surface * event_mask :: the event mask (mode) * * * event :: the returned event * * * 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