1
0
mirror of https://git.code.sf.net/p/fuse-emulator/fuse synced 2026-01-28 14:20:54 +03:00
Files
fuse/widget/widget.c
Philip Kendall d75bf87c9a Use my own scandir replacement in all cases. Avoids compatibility
problems between different Unicies.

Legacy-ID: 92
2001-10-11 15:37:12 +00:00

276 lines
7.0 KiB
C

/* widget.c: Simple dialog boxes for all user interfaces.
Copyright (c) 2001 Matan Ziv-Av, Philip Kendall, Russell Marks
$Id$
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Author contact information:
E-mail: pak21-fuse@srcf.ucam.org
Postal address: 15 Crescent Road, Wokingham, Berks, RG40 2DB, England
*/
#include <config.h>
#include <errno.h>
#include <stdlib.h>
#include <signal.h>
#include <stdio.h>
#include <string.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <sys/time.h>
#include <unistd.h>
#include "fuse.h"
#include "display.h"
#include "machine.h"
#include "ui.h"
#include "uidisplay.h"
#include "keyboard.h"
#include "widget.h"
static void printchar(int x, int y, int col, int ch);
static char widget_font[768];
#define ERROR_MESSAGE_MAX_LENGTH 1024
static int widget_read_font( const char *filename, size_t offset )
{
int fd; struct stat file_info; unsigned char *buffer;
char error_message[ ERROR_MESSAGE_MAX_LENGTH ];
fd = machine_find_rom( filename );
if( fd == -1 ) {
fprintf( stderr,"%s: couldn't find ROM `%s'\n", fuse_progname, filename );
return 1;
}
if( fstat( fd, &file_info) ) {
snprintf( error_message, ERROR_MESSAGE_MAX_LENGTH,
"%s: Couldn't stat `%s'", fuse_progname, filename );
perror( error_message );
close(fd);
return errno;
}
buffer = mmap( 0, file_info.st_size, PROT_READ, MAP_SHARED, fd, 0 );
if( buffer == (void*)-1 ) {
snprintf( error_message, ERROR_MESSAGE_MAX_LENGTH,
"%s: Couldn't mmap `%s'", fuse_progname, filename );
perror( error_message );
close(fd);
return errno;
}
if( close(fd) ) {
snprintf( error_message, ERROR_MESSAGE_MAX_LENGTH,
"%s: Couldn't close `%s'", fuse_progname, filename );
perror( error_message );
munmap( buffer, file_info.st_size );
return errno;
}
memcpy( widget_font, buffer+offset-1, 768 );
if( munmap( buffer, file_info.st_size ) == -1 ) {
snprintf( error_message, ERROR_MESSAGE_MAX_LENGTH,
"%s: Couldn't munmap `%s'", fuse_progname, filename );
perror( error_message );
return errno;
}
return 0;
}
static void printchar(int x, int y, int col, int ch) {
int mx, my;
if((ch<32)||(ch>127)) ch=33;
ch-=32;
for(my=0; my<8; my++) {
int b;
b=widget_font[ch*8+my];
for(mx=0; mx<8; mx++) {
if(b&128) uidisplay_putpixel(mx+DISPLAY_BORDER_WIDTH+8*x, my+DISPLAY_BORDER_HEIGHT+8*y, col);
b<<=1;
}
}
}
void widget_printstring(int x, int y, int col, char *s)
{
int i;
i=0;
if(s) {
while((x<32) && s[i]) {
printchar(x,y,col,s[i]);
i++;
x++;
}
}
}
void widget_rectangle( int x, int y, int w, int h, int col )
{
int mx, my;
for(my=0;my<h;my++)for(mx=0;mx<w;mx++)
uidisplay_putpixel(mx+DISPLAY_BORDER_WIDTH+x, my+DISPLAY_BORDER_HEIGHT+y, col);
}
/* Are we in a widget at the moment? (Used by the key handling routines
to know whether to call the Spectrum or widget key handler) */
int widget_active;
/* The keyhandler to use for the current widget */
widget_keyhandler_fn widget_keyhandler;
/* Have we finished with this widget, and if so in which way? */
widget_finish_state widget_finished;
/* Global initialisation/end routines */
int widget_init( void )
{
int error;
error = widget_read_font( "48.rom", 15617 );
if( error ) return error;
widget_filenames = NULL;
widget_numfiles = 0;
return 0;
}
int widget_end( void )
{
int i;
if( widget_filenames ) {
for( i=0; i<widget_numfiles; i++) {
free( widget_filenames[i]->name );
free( widget_filenames[i] );
}
free( widget_filenames );
}
return 0;
}
/* Widget timer routines */
static struct sigaction widget_timer_old_handler;
static struct itimerval widget_timer_old_timer;
static void widget_timer_signal( int signo );
int widget_timer_init( void )
{
struct sigaction handler;
struct itimerval timer;
handler.sa_handler = widget_timer_signal;
sigemptyset( &handler.sa_mask );
handler.sa_flags = 0;
sigaction( SIGALRM, &handler, &widget_timer_old_handler );
timer.it_interval.tv_sec = 0;
timer.it_interval.tv_usec = 100000UL;
timer.it_value.tv_sec = 0;
timer.it_value.tv_usec = 100000UL;
setitimer( ITIMER_REAL, &timer, &widget_timer_old_timer );
return 0;
}
/* The signal handler: just wake up */
static void widget_timer_signal( int signo )
{
return;
}
int widget_timer_end( void )
{
/* Restore the old timer */
setitimer( ITIMER_REAL, &widget_timer_old_timer, NULL);
/* And the old signal handler */
sigaction( SIGALRM, &widget_timer_old_handler, NULL);
return 0;
}
/* End of timer functions */
int widget_dialog( int x, int y, int width, int height )
{
widget_rectangle( 8*x, 8*y, 8*width, 8*height, WIDGET_COLOUR_BACKGROUND );
return 0;
}
int widget_dialog_with_border( int x, int y, int width, int height )
{
int i;
widget_rectangle( 8*(x-1), 8*(y-1), 8*(width+2), 8*(height+2),
WIDGET_COLOUR_BACKGROUND );
for( i=(8*x)-1; i<(8*(x+width))+1; i++ ) {
uidisplay_putpixel( i + DISPLAY_BORDER_WIDTH,
(8* y )-4 + DISPLAY_BORDER_HEIGHT,
WIDGET_COLOUR_FOREGROUND );
uidisplay_putpixel( i + DISPLAY_BORDER_WIDTH,
(8*(y+height))+3 + DISPLAY_BORDER_HEIGHT,
WIDGET_COLOUR_FOREGROUND );
}
for( i=(8*y)-1; i<(8*(y+height))+1; i++ ) {
uidisplay_putpixel( (8* x )-4 + DISPLAY_BORDER_WIDTH,
i + DISPLAY_BORDER_HEIGHT,
WIDGET_COLOUR_FOREGROUND );
uidisplay_putpixel( (8*(x+width ))+3 + DISPLAY_BORDER_WIDTH,
i + DISPLAY_BORDER_HEIGHT,
WIDGET_COLOUR_FOREGROUND );
}
for( i=0; i<2; i++ ) {
uidisplay_putpixel( (8* x )-3+i + DISPLAY_BORDER_WIDTH,
(8* y )-2-i + DISPLAY_BORDER_HEIGHT,
WIDGET_COLOUR_FOREGROUND );
uidisplay_putpixel( (8*(x+width) )+2-i + DISPLAY_BORDER_WIDTH,
(8* y )-2-i + DISPLAY_BORDER_HEIGHT,
WIDGET_COLOUR_FOREGROUND );
uidisplay_putpixel( (8* x )-3+i + DISPLAY_BORDER_WIDTH,
(8*(y+height))+1+i + DISPLAY_BORDER_HEIGHT,
WIDGET_COLOUR_FOREGROUND );
uidisplay_putpixel( (8*(x+width) )+2-i + DISPLAY_BORDER_WIDTH,
(8*(y+height))+1+i + DISPLAY_BORDER_HEIGHT,
WIDGET_COLOUR_FOREGROUND );
}
uidisplay_lines( DISPLAY_BORDER_HEIGHT + 8*(y -1),
DISPLAY_BORDER_HEIGHT + 8*(y+height+1) );
return 0;
}