2021-08-28 15:37:32 +00:00
# include "cfg.h"
# ifdef GRDRV_GRX
# include "links.h"
# include <grx20.h>
# include "arrow.inc"
# define NUMBER_OF_DEVICES 12
static void grx_mouse_init ( void ) ;
static void grx_mouse_terminate ( void ) ;
void _GrCloseVideoDriver ( void ) ;
extern struct graphics_driver grx_driver ;
static struct itrm * svgalib_kbd ;
static unsigned char * grx_driver_param = NULL ;
static struct graphics_device * grx_old_vd ;
static unsigned char in_graphics_mode = 0 ;
# define TEST_INACTIVITY if (dev != current_virtual_device || !dev->clip.x2) return;
# define TEST_INACTIVITY_0 if (dev != current_virtual_device || !dev->clip.x2) return 0;
static void grx_set_palette ( void )
{
unsigned i , colors ;
if ( grx_driver . depth = = 33 )
colors = 16 ;
else if ( grx_driver . depth = = ( 65 | 0x300 ) )
colors = 216 ;
else if ( grx_driver . depth = = 65 )
colors = 256 ;
else
return ;
GrResetColors ( ) ;
for ( i = 0 ; i < colors ; i + + ) {
unsigned rgb [ 3 ] ;
q_palette ( colors , i , 255 , rgb ) ;
GrSetColor ( i , rgb [ 0 ] , rgb [ 1 ] , rgb [ 2 ] ) ;
}
return ;
}
static void grx_update_palette ( void )
{
int new_depth ;
if ( ! grx_driver . param - > palette_mode )
new_depth = grx_driver . depth | 0x300 ;
else
new_depth = grx_driver . depth & ~ 0x300 ;
if ( new_depth = = grx_driver . depth )
return ;
grx_driver . depth = new_depth ;
grx_driver . get_color = get_color_fn ( new_depth ) ;
if ( ! grx_driver . get_color ) internal_error ( " Unknown bit depth %x " , new_depth ) ;
grx_mouse_terminate ( ) ;
grx_set_palette ( ) ;
grx_mouse_init ( ) ;
}
static void grx_set_text ( void )
{
if ( in_graphics_mode ) {
GrSetMode ( GR_default_text ) ;
in_graphics_mode = 0 ;
_GrCloseVideoDriver ( ) ;
restore_terminal ( ) ;
}
}
static void grx_restore ( void )
{
if ( grx_driver_param ) mem_free ( grx_driver_param ) , grx_driver_param = NULL ;
grx_set_text ( ) ;
}
static void grx_set_clip ( void )
{
GrSetClipBox (
current_virtual_device - > clip . x1 ,
current_virtual_device - > clip . y1 ,
current_virtual_device - > clip . x2 - 1 ,
current_virtual_device - > clip . y2 - 1
) ;
}
static void grx_key_in ( struct itrm * p , unsigned char * ev_ , int size )
{
int vd ;
struct links_event * ev = ( struct links_event * ) ( void * ) ev_ ;
if ( size ! = sizeof ( struct links_event ) ) return ;
if ( ev - > ev = = EV_ABORT ) terminate_loop = 1 ;
if ( ev - > ev ! = EV_KBD ) return ;
if ( ev - > y & KBD_PASTING ) goto skip ;
if ( ( ( ev - > y & ( KBD_CTRL | KBD_ALT ) ) = = KBD_ALT ) & & ev - > x > = ' 0 ' & & ev - > x < = ' 9 ' ) {
vd = ( ev - > x - ' 1 ' + 10 ) % 10 ;
goto switch_vd ;
}
if ( ( ( ev - > y & ( KBD_CTRL | KBD_ALT ) ) = = KBD_ALT ) & & ev - > x = = ' - ' ) {
vd = 10 ;
goto switch_vd ;
}
if ( ( ( ev - > y & ( KBD_CTRL | KBD_ALT ) ) = = KBD_ALT ) & & ev - > x = = ' = ' ) {
vd = 11 ;
goto switch_vd ;
}
if ( ( ( ev - > y & ( KBD_CTRL | KBD_ALT ) ) = = KBD_ALT ) & & ev - > x < = KBD_F1 & & ev - > x > = KBD_F12 ) {
vd = KBD_F1 - ev - > x ;
goto switch_vd ;
}
skip :
if ( g_kbd_codepage ( & grx_driver ) ! = utf8_table & & ev - > x > = 128 & & ev - > x < = 255 )
if ( ( ev - > x = cp2u ( ev - > x , g_kbd_codepage ( & grx_driver ) ) ) = = - 1 ) return ;
if ( current_virtual_device & & current_virtual_device - > keyboard_handler ) current_virtual_device - > keyboard_handler ( current_virtual_device , ev - > x , ev - > y ) ;
return ;
switch_vd :
switch_virtual_device ( vd ) ;
grx_set_clip ( ) ;
}
int grx_mouse_initialized = 0 ;
static GrCursor * grx_mouse_cursor ;
static void grx_mouse_init ( void )
{
int x , y ;
static unsigned char cursor [ arrow_area ] ;
static GrColor table [ 3 ] ;
if ( ! GrMouseDetect ( ) ) return ;
grx_mouse_initialized = 1 ;
GrMouseInit ( ) ;
GrMouseEventEnable ( 0 , 1 ) ;
memset ( & table , 0 , sizeof table ) ;
table [ 0 ] = 2 ;
table [ 1 ] = grx_driver . get_color ( 0 ) ;
table [ 2 ] = grx_driver . get_color ( 0xffffff ) ;
for ( y = 0 ; y < arrow_height ; y + + )
for ( x = 0 ; x < arrow_width ; x + + )
cursor [ y * arrow_width + x ] =
( arrow [ 2 * y ] > > ( arrow_width - x - 1 ) ) & 1 ? 1 :
( arrow [ 2 * y + 1 ] > > ( arrow_width - x - 1 ) ) & 1 ? 2 :
0 ;
grx_mouse_cursor = GrBuildCursor ( cast_char cursor , arrow_width , arrow_width , arrow_height , 0 , 0 , table ) ;
if ( ! grx_mouse_cursor ) GrMouseSetColors ( grx_driver . get_color ( 0xffffff ) , grx_driver . get_color ( 0x000000 ) ) ;
else GrMouseSetCursor ( grx_mouse_cursor ) ;
GrMouseDisplayCursor ( ) ;
}
static void grx_mouse_terminate ( void )
{
if ( ! grx_mouse_initialized ) return ;
GrMouseEraseCursor ( ) ;
GrMouseUnInit ( ) ;
if ( grx_mouse_cursor ) GrDestroyCursor ( grx_mouse_cursor ) ;
grx_mouse_initialized = 0 ;
}
void grx_mouse_poll ( void )
{
int x = GrMousePendingEvent ( ) ;
x = x ;
}
static void grx_do_event ( GrMouseEvent * ev , int b )
{
if ( ! current_virtual_device ) return ;
if ( current_virtual_device - > mouse_handler ) current_virtual_device - > mouse_handler ( current_virtual_device , ev - > x , ev - > y , b ) ;
}
int grx_mouse_event ( void )
{
int e ;
GrMouseEvent ev ;
e = 0 ;
get_another :
GrMouseGetEvent ( GR_M_MOTION | GR_M_BUTTON_CHANGE | GR_M_POLL , & ev ) ;
if ( ev . flags & GR_M_LEFT_DOWN ) grx_do_event ( & ev , B_LEFT | B_DOWN ) , e = 1 ;
if ( ev . flags & GR_M_LEFT_UP ) grx_do_event ( & ev , B_LEFT | B_UP ) , e = 1 ;
if ( ev . flags & GR_M_RIGHT_DOWN ) grx_do_event ( & ev , B_RIGHT | B_DOWN ) , e = 1 ;
if ( ev . flags & GR_M_RIGHT_UP ) grx_do_event ( & ev , B_RIGHT | B_UP ) , e = 1 ;
if ( ev . flags & GR_M_MIDDLE_DOWN ) grx_do_event ( & ev , B_MIDDLE | B_DOWN ) , e = 1 ;
if ( ev . flags & GR_M_MIDDLE_UP ) grx_do_event ( & ev , B_MIDDLE | B_UP ) , e = 1 ;
if ( ev . flags & GR_M_P4_DOWN ) grx_do_event ( & ev , B_WHEELUP | B_MOVE ) , e = 1 ;
if ( ev . flags & GR_M_P5_DOWN ) grx_do_event ( & ev , B_WHEELDOWN | B_MOVE ) , e = 1 ;
if ( ! e & & ev . flags & GR_M_MOTION ) {
if ( GrMousePendingEvent ( ) )
goto get_another ;
grx_do_event ( & ev ,
ev . buttons & GR_M_LEFT ? B_LEFT | B_DRAG :
ev . buttons & GR_M_RIGHT ? B_RIGHT | B_DRAG :
ev . buttons & GR_M_MIDDLE ? B_DRAG | B_MIDDLE : B_MOVE ) , e = 1 ;
}
return e ;
}
static unsigned char * set_mode_according_to_param ( unsigned char * param )
{
unsigned char e [ MAX_STR_LEN ] ;
save_terminal ( ) ;
if ( ! param | | ! * param ) {
return stracpy ( cast_uchar " There is no default videomode. \n Use the switch \" -mode WIDTHxHEIGHTxCOLORS \" to select video mode. \n The COLORS argument may be 16, 256, 32k, 64k, 16M. \n " ) ;
#if 0
if ( ! GrSetMode ( GR_default_graphics ) )
return stracpy ( cast_uchar " GrSetMode failed. \n " ) ;
in_graphics_mode = 1 ;
# endif
} else {
unsigned long x , y ;
int pl ;
unsigned char * ptr = param ;
char * end ;
x = strtoul ( cast_const_char ptr , & end , 10 ) ;
if ( cast_uchar end = = ptr | | * end ! = ' x ' | | x > = MAXINT )
goto bad_param ;
ptr = cast_uchar end + 1 ;
y = strtoul ( cast_const_char ptr , & end , 10 ) ;
if ( cast_uchar end = = ptr | | * end ! = ' x ' | | y > = MAXINT )
goto bad_param ;
ptr = cast_uchar end + 1 ;
if ( ! strcmp ( cast_const_char ptr , " 16 " ) ) pl = 4 ;
else if ( ! strcmp ( cast_const_char ptr , " 256 " ) ) pl = 8 ;
else if ( ! casestrcmp ( ptr , cast_uchar " 32k " ) | | ! strcmp ( cast_const_char ptr , " 32768 " ) ) pl = 15 ;
else if ( ! casestrcmp ( ptr , cast_uchar " 64k " ) | | ! strcmp ( cast_const_char ptr , " 65536 " ) ) pl = 16 ;
else if ( ! casestrcmp ( ptr , cast_uchar " 16M " ) | | ! casestrcmp ( ptr , cast_uchar " 16M32 " ) | | ! strcmp ( cast_const_char ptr , " 16777216 " ) ) pl = 24 ;
else goto bad_param ;
if ( x = = 800 & & y = = 600 & & pl = = 4 ) y = 599 ; /* a bug in GRX */
if ( ! GrSetMode ( GR_width_height_bpp_graphics , ( int ) x , ( int ) y , pl ) ) {
snprintf ( cast_char e , MAX_STR_LEN , " GrSetMode(%lu,%lu,%d) failed. \n " , x , y , pl ) ;
return stracpy ( e ) ;
}
in_graphics_mode = 1 ;
}
return NULL ;
bad_param :
return stracpy ( cast_uchar " Bad -mode parameter. \n " ) ;
}
static void grx_set_graphics ( void )
{
if ( ! in_graphics_mode ) {
unsigned char * er ;
er = set_mode_according_to_param ( grx_driver_param ) ;
if ( er )
fatal_exit ( " grx: Unable to restore video mode '%s': %s " , grx_driver_param , er ) ;
}
}
static unsigned char * grx_init_driver ( unsigned char * param , unsigned char * ignore )
{
unsigned char e [ MAX_STR_LEN ] ;
unsigned char * er ;
const GrVideoMode * mode ;
const GrFrameDriver * fd ;
kbd_set_raw = 1 ;
grx_old_vd = NULL ;
er = set_mode_according_to_param ( param ) ;
if ( er )
return er ;
mode = GrCurrentVideoMode ( ) ;
fd = GrScreenFrameDriver ( ) ;
if ( GrNumPlanes ( ) ! = ( mode - > bpp = = 4 ? 4 : 1 ) ) {
unsupported_videomode :
snprintf ( cast_char e , MAX_STR_LEN , " Unsupported videomode: x %d, y %d, bpp (%d, %d), planes %d. \n " , mode - > width , mode - > height , mode - > bpp , fd - > bits_per_pixel , ( int ) GrNumPlanes ( ) ) ;
grx_restore ( ) ;
return stracpy ( e ) ;
}
grx_driver . flags & = ~ GD_SELECT_PALETTE ;
switch ( mode - > bpp ) {
case 4 :
grx_driver . depth = 33 ;
break ;
case 8 :
grx_driver . depth = 65 ;
if ( ! grx_driver . param - > palette_mode )
grx_driver . depth | = 0x300 ;
grx_driver . flags | = GD_SELECT_PALETTE ;
break ;
case 15 :
grx_driver . depth = 122 ;
break ;
case 16 :
grx_driver . depth = 130 ;
break ;
case 24 :
case 32 :
if ( fd - > bits_per_pixel = = 24 )
grx_driver . depth = 195 ;
else if ( fd - > bits_per_pixel = = 32 )
grx_driver . depth = 196 ;
else
goto unsupported_videomode ;
break ;
default :
goto unsupported_videomode ;
}
grx_driver . get_color = get_color_fn ( grx_driver . depth ) ;
if ( ! grx_driver . get_color ) internal_error ( " Unknown bit depth %x " , grx_driver . depth ) ;
grx_driver . x = mode - > width ;
grx_driver . y = mode - > height ;
if ( mode - > bpp > = 8 ) grx_driver . flags | = GD_DONT_USE_SCROLL ;
else grx_driver . flags & = ~ GD_DONT_USE_SCROLL ;
/*fatal_exit("current mode: %d,%d,%d planes %d bits %d %d", mode->width, mode->height, mode->bpp, GrNumPlanes(), GrScreenFrameDriver()->bits_per_pixel, mode->bpp);*/
grx_set_palette ( ) ;
grx_driver_param = stracpy ( param ? param : cast_uchar " " ) ;
init_virtual_devices ( & grx_driver , NUMBER_OF_DEVICES ) ;
svgalib_kbd = handle_svgalib_keyboard ( grx_key_in ) ;
grx_mouse_init ( ) ;
return NULL ;
}
static void grx_shutdown_driver ( void )
{
shutdown_virtual_devices ( ) ;
grx_mouse_terminate ( ) ;
svgalib_free_trm ( svgalib_kbd ) ;
grx_restore ( ) ;
}
static void grx_emergency_shutdown ( void )
{
grx_restore ( ) ;
}
static unsigned char * grx_get_driver_param ( void )
{
return grx_driver_param ;
}
struct grx_bmp {
GrContext c ;
} ;
static int grx_get_empty_bitmap ( struct bitmap * bmp )
{
struct grx_bmp * b ;
if ( ! in_graphics_mode )
internal_error ( " grx_get_empty_bitmap: not in graphics mode " ) ;
b = mem_alloc_mayfail ( sizeof ( struct grx_bmp ) ) ;
if ( ! b ) goto fail0 ;
again1 :
if ( ! GrCreateContext ( bmp - > x , bmp - > y , NULL , & b - > c ) ) {
if ( out_of_memory ( 0 , NULL , 0 ) )
goto again1 ;
goto fail1 ;
}
bmp - > flags = b ;
if ( GrNumPlanes ( ) = = 1 ) {
bmp - > data = b - > c . gc_baseaddr [ 0 ] ;
bmp - > skip = b - > c . gc_lineoffset ;
} else {
if ( bmp - > x & & ( unsigned ) bmp - > x * ( unsigned ) bmp - > y / ( unsigned ) bmp - > x ! = ( unsigned ) bmp - > y ) goto fail2 ;
if ( ( unsigned ) bmp - > x * ( unsigned ) bmp - > y > ( unsigned ) MAXINT ) goto fail2 ;
bmp - > skip = bmp - > x ;
bmp - > data = mem_alloc_mayfail ( bmp - > skip * bmp - > y ) ;
if ( ! bmp - > data ) goto fail2 ;
}
return 0 ;
fail2 :
GrDestroyContext ( & b - > c ) ;
fail1 :
mem_free ( b ) ;
fail0 :
bmp - > data = NULL ;
bmp - > flags = NULL ;
return - 1 ;
}
static void grx_copy_planes ( struct bitmap * bmp , int y , int n )
{
struct grx_bmp * b = bmp - > flags ;
int j ;
if ( ! b ) return ;
for ( j = 0 ; j < n ; y + + , j + + ) {
int i ;
for ( i = 0 ; i < GrNumPlanes ( ) ; i + + ) {
int x ;
unsigned char * src = ( unsigned char * ) bmp - > data + bmp - > skip * j ;
unsigned char * dst = ( unsigned char * ) b - > c . gc_baseaddr [ i ] + y * b - > c . gc_lineoffset ;
unsigned char byt = 0 ;
for ( x = 0 ; x < bmp - > x ; ) {
unsigned char bit = ( * src + + > > i ) & 1 ;
byt | = bit < < ( ( x & 7 ) ^ 7 ) ;
x + + ;
if ( ! ( x & 7 ) ) * dst + + = byt , byt = 0 ;
}
if ( x & 7 ) * dst = byt ;
}
}
}
static void grx_register_bitmap ( struct bitmap * bmp )
{
if ( GrNumPlanes ( ) ! = 1 ) {
grx_copy_planes ( bmp , 0 , bmp - > y ) ;
mem_free ( bmp - > data ) ;
}
}
static void * grx_prepare_strip ( struct bitmap * bmp , int top , int lines )
{
struct grx_bmp * b = bmp - > flags ;
if ( ! b ) return NULL ;
if ( GrNumPlanes ( ) ! = 1 ) {
bmp - > data = mem_alloc_mayfail ( bmp - > skip * lines ) ;
return bmp - > data ;
}
return ( ( unsigned char * ) bmp - > data ) + bmp - > skip * top ;
}
static void grx_commit_strip ( struct bitmap * bmp , int top , int lines )
{
if ( GrNumPlanes ( ) ! = 1 ) {
if ( ! bmp - > data ) return ;
grx_copy_planes ( bmp , top , lines ) ;
mem_free ( bmp - > data ) ;
}
}
static void grx_unregister_bitmap ( struct bitmap * bmp )
{
struct grx_bmp * b = bmp - > flags ;
if ( ! b ) return ;
GrDestroyContext ( & b - > c ) ;
mem_free ( b ) ;
}
static void grx_draw_bitmap ( struct graphics_device * dev , struct bitmap * bmp , int x , int y )
{
struct grx_bmp * b = bmp - > flags ;
if ( ! b ) return ;
TEST_INACTIVITY
CLIP_DRAW_BITMAP
/* note: GrImageDisplay has buggy clipping.
It doesn ' t draw if the target x or y coordinate is one pixel
before the end of clip area */
GrBitBlt ( NULL , x , y , & b - > c , 0 , 0 , bmp - > x - 1 , bmp - > y - 1 , GrWRITE ) ;
}
static void grx_fill_area ( struct graphics_device * dev , int x1 , int y1 , int x2 , int y2 , long color )
{
TEST_INACTIVITY
CLIP_FILL_AREA
if ( x1 > = x2 | | y1 > = y2 ) return ;
GrFilledBox ( x1 , y1 , x2 - 1 , y2 - 1 , color ) ;
}
static void grx_draw_hline ( struct graphics_device * dev , int x1 , int y , int x2 , long color )
{
TEST_INACTIVITY
CLIP_DRAW_HLINE
GrHLine ( x1 , x2 - 1 , y , color ) ;
}
static void grx_draw_vline ( struct graphics_device * dev , int x , int y1 , int y2 , long color )
{
TEST_INACTIVITY
CLIP_DRAW_VLINE
GrVLine ( x , y1 , y2 - 1 , color ) ;
}
static int grx_scroll ( struct graphics_device * dev , struct rect_set * * ignore , int scx , int scy )
{
TEST_INACTIVITY_0
GrBitBlt ( NULL ,
dev - > clip . x1 + ( scx > = 0 ? scx : 0 ) ,
dev - > clip . y1 + ( scy > = 0 ? scy : 0 ) ,
NULL ,
dev - > clip . x1 - ( scx < 0 ? scx : 0 ) ,
dev - > clip . y1 - ( scy < 0 ? scy : 0 ) ,
dev - > clip . x2 - ( scx > = 0 ? scx : 0 ) - 1 ,
dev - > clip . y2 - ( scy > = 0 ? scy : 0 ) - 1 ,
GrWRITE ) ;
return 1 ;
}
static void grx_set_clip_area ( struct graphics_device * dev )
{
if ( dev ! = current_virtual_device ) return ;
grx_set_clip ( ) ;
}
static int grx_block ( struct graphics_device * dev )
{
if ( grx_old_vd ) return 1 ;
grx_old_vd = current_virtual_device ;
current_virtual_device = NULL ;
grx_mouse_terminate ( ) ;
svgalib_block_itrm ( svgalib_kbd ) ;
grx_set_text ( ) ;
return 0 ;
}
static int grx_unblock ( struct graphics_device * dev )
{
if ( current_virtual_device ) {
internal_error ( " grx_unblock called without grx_block " ) ;
return 0 ;
}
grx_set_graphics ( ) ;
svgalib_unblock_itrm ( svgalib_kbd ) ;
current_virtual_device = grx_old_vd ;
grx_old_vd = NULL ;
grx_set_palette ( ) ;
grx_set_clip ( ) ;
grx_mouse_init ( ) ;
if ( current_virtual_device ) current_virtual_device - > redraw_handler ( current_virtual_device , & current_virtual_device - > size ) ;
return 0 ;
}
struct graphics_driver grx_driver = {
cast_uchar " grx " ,
grx_init_driver ,
init_virtual_device ,
shutdown_virtual_device ,
grx_shutdown_driver ,
grx_emergency_shutdown ,
NULL ,
grx_get_driver_param ,
NULL ,
NULL ,
NULL ,
grx_get_empty_bitmap ,
grx_register_bitmap ,
grx_prepare_strip ,
grx_commit_strip ,
grx_unregister_bitmap ,
grx_draw_bitmap ,
NULL ,
grx_fill_area ,
grx_draw_hline ,
grx_draw_vline ,
grx_scroll ,
grx_set_clip_area ,
2024-01-21 19:57:51 +00:00
NULL , /* start_draw */
NULL , /* end_draw */
2021-08-28 15:37:32 +00:00
NULL ,
grx_block ,
grx_unblock ,
grx_update_palette , /* set_palette */
NULL , /* get_real_colors */
NULL , /* set_title */
NULL , /* exec */
NULL , /* set_clipboard_text */
NULL , /* get_clipboard_text */
0 , /* depth */
0 , 0 , /* size */
GD_NEED_CODEPAGE , /* flags */
NULL , /* param */
} ;
# endif