From 89c35e1604345f75bd72c5319a953b6eab19a8e2 Mon Sep 17 00:00:00 2001 From: Gwenhael Le Moine Date: Wed, 20 Sep 2023 10:34:27 +0200 Subject: [PATCH 01/11] recent first --- dist/x48ng.man.1 | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/dist/x48ng.man.1 b/dist/x48ng.man.1 index bb0cb5c..7105da7 100644 --- a/dist/x48ng.man.1 +++ b/dist/x48ng.man.1 @@ -174,15 +174,15 @@ The colors are therefore not selectable. .PP Bugs can be found and reported at: https://github.com/gwenhael-le-moine/x48ng .SH COPYRIGHT -Copyright \(co 1994-2005 Eddie C. Dost -.br Copyright \(co 2023- Gwenhael Le Moine .br +Copyright \(co 1994-2005 Eddie C. Dost +.br This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. .SH AUTHORS +Gwenhael Le Moine +.br Eddie C. Dost .br G. Allen Morris III -.br -Gwenhael Le Moine From b73090d017b8dd6a3a3bbc931b2b3731058b0644 Mon Sep 17 00:00:00 2001 From: Gwenhael Le Moine Date: Wed, 20 Sep 2023 10:34:53 +0200 Subject: [PATCH 02/11] dename disp to lcd for clarity, use less variables --- src/ui_x11.c | 360 +++++++++++++++++++++++++-------------------------- 1 file changed, 174 insertions(+), 186 deletions(-) diff --git a/src/ui_x11.c b/src/ui_x11.c index f7f8ea5..e0b6e5d 100644 --- a/src/ui_x11.c +++ b/src/ui_x11.c @@ -300,20 +300,16 @@ typedef struct x11_ann_struct_t { Pixmap pixmap; } x11_ann_struct_t; -typedef struct disp_t { - unsigned int w, h; - +typedef struct x11_lcd_t { Window win; GC gc; - short mapped; - int display_update; XShmSegmentInfo disp_info; XImage* disp_image; XShmSegmentInfo menu_info; XImage* menu_image; -} disp_t; +} x11_lcd_t; typedef struct icon_t { unsigned int w; @@ -322,12 +318,14 @@ typedef struct icon_t { unsigned char* bits; } icon_map_t; +static short mapped; + static x11_keypad_t keypad; static x11_color_t* colors; static int CompletionType = -1; -static disp_t disp; +static x11_lcd_t lcd; static int shm_flag; @@ -2406,8 +2404,6 @@ void CreateKeypad( unsigned int offset_y, unsigned int offset_x, void CreateBezel( x11_keypad_t* keypad ) { int i; - int display_height = DISPLAY_HEIGHT; - int display_width = DISPLAY_WIDTH; /* * draw the frame around the display @@ -2416,18 +2412,18 @@ void CreateBezel( x11_keypad_t* keypad ) { for ( i = 0; i < DISP_FRAME; i++ ) { XDrawLine( dpy, keypad->pixmap, gc, ( int )( DISPLAY_OFFSET_X - i ), - ( int )( DISPLAY_OFFSET_Y + display_height + 2 * i ), - ( int )( DISPLAY_OFFSET_X + display_width + i ), - ( int )( DISPLAY_OFFSET_Y + display_height + 2 * i ) ); + ( int )( DISPLAY_OFFSET_Y + DISPLAY_HEIGHT + 2 * i ), + ( int )( DISPLAY_OFFSET_X + DISPLAY_WIDTH + i ), + ( int )( DISPLAY_OFFSET_Y + DISPLAY_HEIGHT + 2 * i ) ); XDrawLine( dpy, keypad->pixmap, gc, ( int )( DISPLAY_OFFSET_X - i ), - ( int )( DISPLAY_OFFSET_Y + display_height + 2 * i + 1 ), - ( int )( DISPLAY_OFFSET_X + display_width + i ), - ( int )( DISPLAY_OFFSET_Y + display_height + 2 * i + 1 ) ); + ( int )( DISPLAY_OFFSET_Y + DISPLAY_HEIGHT + 2 * i + 1 ), + ( int )( DISPLAY_OFFSET_X + DISPLAY_WIDTH + i ), + ( int )( DISPLAY_OFFSET_Y + DISPLAY_HEIGHT + 2 * i + 1 ) ); XDrawLine( dpy, keypad->pixmap, gc, - ( int )( DISPLAY_OFFSET_X + display_width + i ), + ( int )( DISPLAY_OFFSET_X + DISPLAY_WIDTH + i ), ( int )( DISPLAY_OFFSET_Y - i ), - ( int )( DISPLAY_OFFSET_X + display_width + i ), - ( int )( DISPLAY_OFFSET_Y + display_height + 2 * i ) ); + ( int )( DISPLAY_OFFSET_X + DISPLAY_WIDTH + i ), + ( int )( DISPLAY_OFFSET_Y + DISPLAY_HEIGHT + 2 * i ) ); } XSetForeground( dpy, gc, COLOR( DISP_PAD_BOT ) ); @@ -2435,12 +2431,12 @@ void CreateBezel( x11_keypad_t* keypad ) { for ( i = 0; i < DISP_FRAME; i++ ) { XDrawLine( dpy, keypad->pixmap, gc, ( int )( DISPLAY_OFFSET_X - i - 1 ), ( int )( DISPLAY_OFFSET_Y - i - 1 ), - ( int )( DISPLAY_OFFSET_X + display_width + i - 1 ), + ( int )( DISPLAY_OFFSET_X + DISPLAY_WIDTH + i - 1 ), ( int )( DISPLAY_OFFSET_Y - i - 1 ) ); XDrawLine( dpy, keypad->pixmap, gc, ( int )( DISPLAY_OFFSET_X - i - 1 ), ( int )( DISPLAY_OFFSET_Y - i - 1 ), ( int )( DISPLAY_OFFSET_X - i - 1 ), - ( int )( DISPLAY_OFFSET_Y + display_height + 2 * i - 1 ) ); + ( int )( DISPLAY_OFFSET_Y + DISPLAY_HEIGHT + 2 * i - 1 ) ); } /* @@ -2463,49 +2459,49 @@ void CreateBezel( x11_keypad_t* keypad ) { ( int )( DISPLAY_OFFSET_Y - DISP_FRAME + 1 ) ); XDrawLine( dpy, keypad->pixmap, gc, - ( int )( DISPLAY_OFFSET_X + display_width + DISP_FRAME - 4 ), + ( int )( DISPLAY_OFFSET_X + DISPLAY_WIDTH + DISP_FRAME - 4 ), ( int )( DISPLAY_OFFSET_Y - DISP_FRAME ), - ( int )( DISPLAY_OFFSET_X + display_width + DISP_FRAME - 1 ), + ( int )( DISPLAY_OFFSET_X + DISPLAY_WIDTH + DISP_FRAME - 1 ), ( int )( DISPLAY_OFFSET_Y - DISP_FRAME ) ); XDrawLine( dpy, keypad->pixmap, gc, - ( int )( DISPLAY_OFFSET_X + display_width + DISP_FRAME - 1 ), + ( int )( DISPLAY_OFFSET_X + DISPLAY_WIDTH + DISP_FRAME - 1 ), ( int )( DISPLAY_OFFSET_Y - DISP_FRAME ), - ( int )( DISPLAY_OFFSET_X + display_width + DISP_FRAME - 1 ), + ( int )( DISPLAY_OFFSET_X + DISPLAY_WIDTH + DISP_FRAME - 1 ), ( int )( DISPLAY_OFFSET_Y - DISP_FRAME + 3 ) ); XDrawPoint( dpy, keypad->pixmap, gc, - ( int )( DISPLAY_OFFSET_X + display_width + DISP_FRAME - 2 ), + ( int )( DISPLAY_OFFSET_X + DISPLAY_WIDTH + DISP_FRAME - 2 ), ( int )( DISPLAY_OFFSET_Y - DISP_FRAME + 1 ) ); XDrawLine( dpy, keypad->pixmap, gc, ( int )( DISPLAY_OFFSET_X - DISP_FRAME ), - ( int )( DISPLAY_OFFSET_Y + display_height + 2 * DISP_FRAME - 4 ), + ( int )( DISPLAY_OFFSET_Y + DISPLAY_HEIGHT + 2 * DISP_FRAME - 4 ), ( int )( DISPLAY_OFFSET_X - DISP_FRAME ), - ( int )( DISPLAY_OFFSET_Y + display_height + 2 * DISP_FRAME - 1 ) ); + ( int )( DISPLAY_OFFSET_Y + DISPLAY_HEIGHT + 2 * DISP_FRAME - 1 ) ); XDrawLine( dpy, keypad->pixmap, gc, ( int )( DISPLAY_OFFSET_X - DISP_FRAME ), - ( int )( DISPLAY_OFFSET_Y + display_height + 2 * DISP_FRAME - 1 ), + ( int )( DISPLAY_OFFSET_Y + DISPLAY_HEIGHT + 2 * DISP_FRAME - 1 ), ( int )( DISPLAY_OFFSET_X - DISP_FRAME + 3 ), - ( int )( DISPLAY_OFFSET_Y + display_height + 2 * DISP_FRAME - 1 ) ); + ( int )( DISPLAY_OFFSET_Y + DISPLAY_HEIGHT + 2 * DISP_FRAME - 1 ) ); XDrawPoint( dpy, keypad->pixmap, gc, ( int )( DISPLAY_OFFSET_X - DISP_FRAME + 1 ), - ( int )( DISPLAY_OFFSET_Y + display_height + 2 * DISP_FRAME - 2 ) ); + ( int )( DISPLAY_OFFSET_Y + DISPLAY_HEIGHT + 2 * DISP_FRAME - 2 ) ); XDrawLine( dpy, keypad->pixmap, gc, - ( int )( DISPLAY_OFFSET_X + display_width + DISP_FRAME - 1 ), - ( int )( DISPLAY_OFFSET_Y + display_height + 2 * DISP_FRAME - 4 ), - ( int )( DISPLAY_OFFSET_X + display_width + DISP_FRAME - 1 ), - ( int )( DISPLAY_OFFSET_Y + display_height + 2 * DISP_FRAME - 1 ) ); + ( int )( DISPLAY_OFFSET_X + DISPLAY_WIDTH + DISP_FRAME - 1 ), + ( int )( DISPLAY_OFFSET_Y + DISPLAY_HEIGHT + 2 * DISP_FRAME - 4 ), + ( int )( DISPLAY_OFFSET_X + DISPLAY_WIDTH + DISP_FRAME - 1 ), + ( int )( DISPLAY_OFFSET_Y + DISPLAY_HEIGHT + 2 * DISP_FRAME - 1 ) ); XDrawLine( dpy, keypad->pixmap, gc, - ( int )( DISPLAY_OFFSET_X + display_width + DISP_FRAME - 4 ), - ( int )( DISPLAY_OFFSET_Y + display_height + 2 * DISP_FRAME - 1 ), - ( int )( DISPLAY_OFFSET_X + display_width + DISP_FRAME - 1 ), - ( int )( DISPLAY_OFFSET_Y + display_height + 2 * DISP_FRAME - 1 ) ); + ( int )( DISPLAY_OFFSET_X + DISPLAY_WIDTH + DISP_FRAME - 4 ), + ( int )( DISPLAY_OFFSET_Y + DISPLAY_HEIGHT + 2 * DISP_FRAME - 1 ), + ( int )( DISPLAY_OFFSET_X + DISPLAY_WIDTH + DISP_FRAME - 1 ), + ( int )( DISPLAY_OFFSET_Y + DISPLAY_HEIGHT + 2 * DISP_FRAME - 1 ) ); XDrawPoint( dpy, keypad->pixmap, gc, - ( int )( DISPLAY_OFFSET_X + display_width + DISP_FRAME - 2 ), - ( int )( DISPLAY_OFFSET_Y + display_height + 2 * DISP_FRAME - 2 ) ); + ( int )( DISPLAY_OFFSET_X + DISPLAY_WIDTH + DISP_FRAME - 2 ), + ( int )( DISPLAY_OFFSET_Y + DISPLAY_HEIGHT + 2 * DISP_FRAME - 2 ) ); /* * simulate rounded lcd corners @@ -2514,20 +2510,20 @@ void CreateBezel( x11_keypad_t* keypad ) { XDrawLine( dpy, keypad->pixmap, gc, ( int )( DISPLAY_OFFSET_X - 1 ), ( int )( DISPLAY_OFFSET_Y + 1 ), ( int )( DISPLAY_OFFSET_X - 1 ), - ( int )( DISPLAY_OFFSET_Y + display_height - 2 ) ); + ( int )( DISPLAY_OFFSET_Y + DISPLAY_HEIGHT - 2 ) ); XDrawLine( dpy, keypad->pixmap, gc, ( int )( DISPLAY_OFFSET_X + 1 ), ( int )( DISPLAY_OFFSET_Y - 1 ), - ( int )( DISPLAY_OFFSET_X + display_width - 2 ), + ( int )( DISPLAY_OFFSET_X + DISPLAY_WIDTH - 2 ), ( int )( DISPLAY_OFFSET_Y - 1 ) ); XDrawLine( dpy, keypad->pixmap, gc, ( int )( DISPLAY_OFFSET_X + 1 ), - ( int )( DISPLAY_OFFSET_Y + display_height ), - ( int )( DISPLAY_OFFSET_X + display_width - 2 ), - ( int )( DISPLAY_OFFSET_Y + display_height ) ); + ( int )( DISPLAY_OFFSET_Y + DISPLAY_HEIGHT ), + ( int )( DISPLAY_OFFSET_X + DISPLAY_WIDTH - 2 ), + ( int )( DISPLAY_OFFSET_Y + DISPLAY_HEIGHT ) ); XDrawLine( dpy, keypad->pixmap, gc, - ( int )( DISPLAY_OFFSET_X + display_width ), + ( int )( DISPLAY_OFFSET_X + DISPLAY_WIDTH ), ( int )( DISPLAY_OFFSET_Y + 1 ), - ( int )( DISPLAY_OFFSET_X + display_width ), - ( int )( DISPLAY_OFFSET_Y + display_height - 2 ) ); + ( int )( DISPLAY_OFFSET_X + DISPLAY_WIDTH ), + ( int )( DISPLAY_OFFSET_Y + DISPLAY_HEIGHT - 2 ) ); } void DrawMore( unsigned int offset_y, x11_keypad_t* keypad ) { @@ -2535,8 +2531,6 @@ void DrawMore( unsigned int offset_y, x11_keypad_t* keypad ) { int cut = 0; int x, y; - // int display_height = DISPLAY_HEIGHT; - int display_width = DISPLAY_WIDTH; /* * lower the whole thing */ @@ -2734,7 +2728,7 @@ void DrawMore( unsigned int offset_y, x11_keypad_t* keypad ) { XSetForeground( dpy, gc, COLOR( LABEL ) ); if ( opt_gx ) { - x = DISPLAY_OFFSET_X + display_width - gx_128K_ram_width + + x = DISPLAY_OFFSET_X + DISPLAY_WIDTH - gx_128K_ram_width + gx_128K_ram_x_hot + 2; y = 10 + gx_128K_ram_y_hot; pix = XCreateBitmapFromData( dpy, keypad->pixmap, @@ -2768,7 +2762,7 @@ void DrawMore( unsigned int offset_y, x11_keypad_t* keypad ) { XFreePixmap( dpy, pix ); XSetForeground( dpy, gc, COLOR( RIGHT ) ); - x = DISPLAY_OFFSET_X + display_width - gx_128K_ram_width + + x = DISPLAY_OFFSET_X + DISPLAY_WIDTH - gx_128K_ram_width + gx_green_x_hot + 2; y = 10 + gx_green_y_hot; pix = XCreateBitmapFromData( dpy, keypad->pixmap, @@ -2795,7 +2789,7 @@ void DrawMore( unsigned int offset_y, x11_keypad_t* keypad ) { XFreePixmap( dpy, pix ); - x = DISPLAY_OFFSET_X + display_width - 1 - science_width; + x = DISPLAY_OFFSET_X + DISPLAY_WIDTH - 1 - science_width; y = TOP_SKIP - DISP_FRAME - science_height - 4; pix = @@ -2953,19 +2947,16 @@ void CreateDispWindow( void ) { /* * create the display subwindow */ - disp.w = DISPLAY_WIDTH; - disp.h = DISPLAY_HEIGHT; + lcd.win = XCreateSimpleWindow( + dpy, mainW, ( int )DISPLAY_OFFSET_X, ( int )DISPLAY_OFFSET_Y, + DISPLAY_WIDTH, DISPLAY_HEIGHT, 0, COLOR( BLACK ), COLOR( LCD ) ); - disp.win = XCreateSimpleWindow( dpy, mainW, ( int )DISPLAY_OFFSET_X, - ( int )DISPLAY_OFFSET_Y, disp.w, disp.h, 0, - COLOR( BLACK ), COLOR( LCD ) ); - - disp.mapped = 1; + mapped = 1; xswa.event_mask = ExposureMask | StructureNotifyMask; xswa.backing_store = Always; - XChangeWindowAttributes( dpy, disp.win, CWEventMask | CWBackingStore, + XChangeWindowAttributes( dpy, lcd.win, CWEventMask | CWBackingStore, &xswa ); /* @@ -2975,26 +2966,25 @@ void CreateDispWindow( void ) { val.background = COLOR( LCD ); val.function = GXcopy; gc_mask = GCForeground | GCBackground | GCFunction; - disp.gc = XCreateGC( dpy, mainW, gc_mask, &val ); + lcd.gc = XCreateGC( dpy, mainW, gc_mask, &val ); - XSetForeground( dpy, disp.gc, COLOR( PIXEL ) ); + XSetForeground( dpy, lcd.gc, COLOR( PIXEL ) ); - disp.display_update = UPDATE_DISP | UPDATE_MENU; + lcd.display_update = UPDATE_DISP | UPDATE_MENU; xerror_flag = 0; XSetErrorHandler( handle_xerror ); XFlush( dpy ); - disp.disp_image = NULL; - disp.menu_image = NULL; + lcd.disp_image = NULL; + lcd.menu_image = NULL; if ( shm_flag ) { - /* * create XShmImage for DISP */ - disp.disp_image = XShmCreateImage( dpy, None, 1, XYBitmap, NULL, - &disp.disp_info, 262, 128 ); - if ( disp.disp_image == NULL ) { + lcd.disp_image = XShmCreateImage( dpy, None, 1, XYBitmap, NULL, + &lcd.disp_info, 262, 128 ); + if ( lcd.disp_image == NULL ) { shm_flag = 0; if ( verbose ) fprintf( stderr, @@ -3005,13 +2995,13 @@ void CreateDispWindow( void ) { /* * get ID of shared memory block for DISP */ - disp.disp_info.shmid = shmget( - IPC_PRIVATE, - ( disp.disp_image->bytes_per_line * disp.disp_image->height ), - IPC_CREAT | 0777 ); - if ( disp.disp_info.shmid < 0 ) { - XDestroyImage( disp.disp_image ); - disp.disp_image = NULL; + lcd.disp_info.shmid = + shmget( IPC_PRIVATE, + ( lcd.disp_image->bytes_per_line * lcd.disp_image->height ), + IPC_CREAT | 0777 ); + if ( lcd.disp_info.shmid < 0 ) { + XDestroyImage( lcd.disp_image ); + lcd.disp_image = NULL; shm_flag = 0; if ( verbose ) fprintf( stderr, "XShm error in shmget(DISP), disabling.\n" ); @@ -3021,27 +3011,27 @@ void CreateDispWindow( void ) { /* * get address of shared memory block for DISP */ - disp.disp_info.shmaddr = ( char* )shmat( disp.disp_info.shmid, 0, 0 ); - if ( disp.disp_info.shmaddr == ( ( char* )-1 ) ) { - XDestroyImage( disp.disp_image ); - disp.disp_image = NULL; + lcd.disp_info.shmaddr = ( char* )shmat( lcd.disp_info.shmid, 0, 0 ); + if ( lcd.disp_info.shmaddr == ( ( char* )-1 ) ) { + XDestroyImage( lcd.disp_image ); + lcd.disp_image = NULL; shm_flag = 0; if ( verbose ) fprintf( stderr, "XShm error in shmat(DISP), disabling.\n" ); goto shm_error; } - disp.disp_image->data = disp.disp_info.shmaddr; - disp.disp_info.readOnly = False; - XShmAttach( dpy, &disp.disp_info ); + lcd.disp_image->data = lcd.disp_info.shmaddr; + lcd.disp_info.readOnly = False; + XShmAttach( dpy, &lcd.disp_info ); /* * create XShmImage for MENU */ - disp.menu_image = XShmCreateImage( dpy, None, 1, XYBitmap, NULL, - &disp.menu_info, 262, 128 ); - if ( disp.menu_image == NULL ) { - XDestroyImage( disp.disp_image ); - disp.disp_image = NULL; + lcd.menu_image = XShmCreateImage( dpy, None, 1, XYBitmap, NULL, + &lcd.menu_info, 262, 128 ); + if ( lcd.menu_image == NULL ) { + XDestroyImage( lcd.disp_image ); + lcd.disp_image = NULL; shm_flag = 0; if ( verbose ) fprintf( stderr, @@ -3052,15 +3042,15 @@ void CreateDispWindow( void ) { /* * get ID of shared memory block for MENU */ - disp.menu_info.shmid = shmget( - IPC_PRIVATE, - ( disp.menu_image->bytes_per_line * disp.menu_image->height ), - IPC_CREAT | 0777 ); - if ( disp.menu_info.shmid < 0 ) { - XDestroyImage( disp.disp_image ); - disp.disp_image = NULL; - XDestroyImage( disp.menu_image ); - disp.menu_image = NULL; + lcd.menu_info.shmid = + shmget( IPC_PRIVATE, + ( lcd.menu_image->bytes_per_line * lcd.menu_image->height ), + IPC_CREAT | 0777 ); + if ( lcd.menu_info.shmid < 0 ) { + XDestroyImage( lcd.disp_image ); + lcd.disp_image = NULL; + XDestroyImage( lcd.menu_image ); + lcd.menu_image = NULL; shm_flag = 0; if ( verbose ) fprintf( stderr, "XShm error in shmget(MENU), disabling.\n" ); @@ -3070,45 +3060,45 @@ void CreateDispWindow( void ) { /* * get address of shared memory block for MENU */ - disp.menu_info.shmaddr = ( char* )shmat( disp.menu_info.shmid, 0, 0 ); - if ( disp.menu_info.shmaddr == ( ( char* )-1 ) ) { - XDestroyImage( disp.disp_image ); - disp.disp_image = NULL; - XDestroyImage( disp.menu_image ); - disp.menu_image = NULL; + lcd.menu_info.shmaddr = ( char* )shmat( lcd.menu_info.shmid, 0, 0 ); + if ( lcd.menu_info.shmaddr == ( ( char* )-1 ) ) { + XDestroyImage( lcd.disp_image ); + lcd.disp_image = NULL; + XDestroyImage( lcd.menu_image ); + lcd.menu_image = NULL; shm_flag = 0; if ( verbose ) fprintf( stderr, "XShm error in shmat(MENU), disabling.\n" ); goto shm_error; } - disp.menu_image->data = disp.menu_info.shmaddr; - disp.menu_info.readOnly = False; - XShmAttach( dpy, &disp.menu_info ); + lcd.menu_image->data = lcd.menu_info.shmaddr; + lcd.menu_info.readOnly = False; + XShmAttach( dpy, &lcd.menu_info ); XFlush( dpy ); XSync( dpy, 0 ); sleep( 1 ); if ( xerror_flag ) { - XDestroyImage( disp.disp_image ); - disp.disp_image = NULL; - XDestroyImage( disp.menu_image ); - disp.menu_image = NULL; + XDestroyImage( lcd.disp_image ); + lcd.disp_image = NULL; + XDestroyImage( lcd.menu_image ); + lcd.menu_image = NULL; shm_flag = 0; if ( verbose ) fprintf( stderr, "XShm error in shmget(MENU), disabling.\n" ); goto shm_error; } else { - shmctl( disp.disp_info.shmid, IPC_RMID, 0 ); - shmctl( disp.menu_info.shmid, IPC_RMID, 0 ); + shmctl( lcd.disp_info.shmid, IPC_RMID, 0 ); + shmctl( lcd.menu_info.shmid, IPC_RMID, 0 ); } - memset( disp.disp_image->data, 0, - ( size_t )( disp.disp_image->bytes_per_line * - disp.disp_image->height ) ); - memset( disp.menu_image->data, 0, - ( size_t )( disp.menu_image->bytes_per_line * - disp.menu_image->height ) ); + memset( lcd.disp_image->data, 0, + ( size_t )( lcd.disp_image->bytes_per_line * + lcd.disp_image->height ) ); + memset( lcd.menu_image->data, 0, + ( size_t )( lcd.menu_image->bytes_per_line * + lcd.menu_image->height ) ); if ( verbose ) printf( "using XShm extension.\n" ); @@ -3124,8 +3114,8 @@ shm_error: rect.x = 5; rect.y = 0; rect.width = 262; - rect.height = disp.h; - XSetClipRectangles( dpy, disp.gc, 0, 0, &rect, 1, Unsorted ); + rect.height = DISPLAY_HEIGHT; + XSetClipRectangles( dpy, lcd.gc, 0, 0, &rect, 1, Unsorted ); } } @@ -3490,8 +3480,8 @@ int CreateWindows( int argc, char** argv ) { DrawSerialDevices( wire_name, ir_name ); if ( shm_flag ) { - XSetForeground( dpy, disp.gc, COLOR( PIXEL ) ); - XFillRectangle( dpy, disp.win, disp.gc, 5, 20, 262, 128 ); + XSetForeground( dpy, lcd.gc, COLOR( PIXEL ) ); + XFillRectangle( dpy, lcd.win, lcd.gc, 5, 20, 262, 128 ); } return 0; @@ -3540,22 +3530,22 @@ void refresh_display( void ) { if ( !shm_flag ) return; - if ( disp.display_update & UPDATE_DISP ) { - XShmPutImage( dpy, disp.win, disp.gc, disp.disp_image, - 2 * display.offset, 0, 5, 20, 262, + if ( lcd.display_update & UPDATE_DISP ) { + XShmPutImage( dpy, lcd.win, lcd.gc, lcd.disp_image, 2 * display.offset, + 0, 5, 20, 262, ( unsigned int )( ( 2 * display.lines ) + 2 ), 0 ); } if ( ( ( 2 * display.lines ) < 126 ) && - ( disp.display_update & UPDATE_MENU ) ) { - XShmPutImage( dpy, disp.win, disp.gc, disp.menu_image, 0, 0, 5, + ( lcd.display_update & UPDATE_MENU ) ) { + XShmPutImage( dpy, lcd.win, lcd.gc, lcd.menu_image, 0, 0, 5, ( int )( ( 2 * display.lines ) + 22 ), 262, ( unsigned int )( 126 - ( 2 * display.lines ) ), 0 ); } - disp.display_update = 0; + lcd.display_update = 0; } void redraw_display( void ) { - XClearWindow( dpy, disp.win ); + XClearWindow( dpy, lcd.win ); memset( disp_buf, 0, sizeof( disp_buf ) ); memset( lcd_buffer, 0, sizeof( lcd_buffer ) ); x11_update_LCD(); @@ -3568,16 +3558,16 @@ void redraw_annunc( void ) { void DrawDisp( void ) { if ( shm_flag ) { - XShmPutImage( dpy, disp.win, disp.gc, disp.disp_image, - 2 * display.offset, 0, 5, 20, 262, + XShmPutImage( dpy, lcd.win, lcd.gc, lcd.disp_image, 2 * display.offset, + 0, 5, 20, 262, ( unsigned int )( ( 2 * display.lines ) + 2 ), 0 ); if ( display.lines < 63 ) { - XShmPutImage( dpy, disp.win, disp.gc, disp.menu_image, 0, + XShmPutImage( dpy, lcd.win, lcd.gc, lcd.menu_image, 0, ( 2 * display.lines ) - 110, 5, 22 + ( 2 * display.lines ), 262, ( unsigned int )( 126 - ( 2 * display.lines ) ), 0 ); } - disp.display_update = 0; + lcd.display_update = 0; } else { redraw_display(); } @@ -4063,8 +4053,8 @@ static inline void draw_nibble( int c, int r, int val ) { y = ( r * 2 ) + 20; val &= 0x0f; if ( val != lcd_buffer[ r ][ c ] ) { - XCopyPlane( dpy, nibble_maps[ val ], disp.win, disp.gc, 0, 0, 8, 2, x, - y, 1 ); + XCopyPlane( dpy, nibble_maps[ val ], lcd.win, lcd.gc, 0, 0, 8, 2, x, y, + 1 ); lcd_buffer[ r ][ c ] = val; } } @@ -4088,7 +4078,7 @@ static inline void draw_row( long addr, int row ) { static inline void init_annunc( void ) { for ( int i = 0; ann_tbl[ i ].bit; i++ ) ann_tbl[ i ].pixmap = - XCreateBitmapFromData( dpy, disp.win, ( char* )ann_tbl[ i ].bits, + XCreateBitmapFromData( dpy, lcd.win, ( char* )ann_tbl[ i ].bits, ann_tbl[ i ].width, ann_tbl[ i ].height ); } @@ -4163,7 +4153,7 @@ int x11_get_event( void ) { case Expose: if ( xev.xexpose.count == 0 ) { - if ( xev.xexpose.window == disp.win ) { + if ( xev.xexpose.window == lcd.win ) { DrawDisp(); } else if ( xev.xexpose.window == iconW ) { DrawIcon(); @@ -4180,13 +4170,13 @@ int x11_get_event( void ) { break; case UnmapNotify: - disp.mapped = 0; + mapped = 0; break; case MapNotify: - if ( !disp.mapped ) { - disp.mapped = 1; + if ( !mapped ) { + mapped = 1; x11_update_LCD(); redraw_annunc(); } @@ -4194,9 +4184,9 @@ int x11_get_event( void ) { case ButtonPress: - if ( xev.xbutton.subwindow == disp.win ) { + if ( xev.xbutton.subwindow == lcd.win ) { if ( xev.xbutton.button == Button2 ) { - if ( xev.xbutton.subwindow == disp.win ) { + if ( xev.xbutton.subwindow == lcd.win ) { int x; int flag = 0; char* paste_in = XFetchBuffer( dpy, &x, 0 ); @@ -4767,8 +4757,8 @@ void x11_adjust_contrast( void ) { colors[ PIXEL ].g = g; colors[ PIXEL ].b = b; AllocColors(); - XSetForeground( dpy, disp.gc, COLOR( PIXEL ) ); - disp.display_update = UPDATE_DISP | UPDATE_MENU; + XSetForeground( dpy, lcd.gc, COLOR( PIXEL ) ); + lcd.display_update = UPDATE_DISP | UPDATE_MENU; refresh_display(); redraw_annunc(); last_icon_state = -1; @@ -4782,8 +4772,8 @@ void x11_adjust_contrast( void ) { fprintf( stderr, "warning: can\'t alloc new pixel color.\n" ); } else { XFreeColors( dpy, cmap, &old, 1, 0 ); - XSetForeground( dpy, disp.gc, COLOR( PIXEL ) ); - disp.display_update = UPDATE_DISP | UPDATE_MENU; + XSetForeground( dpy, lcd.gc, COLOR( PIXEL ) ); + lcd.display_update = UPDATE_DISP | UPDATE_MENU; refresh_display(); redraw_annunc(); last_icon_state = -1; @@ -4826,12 +4816,12 @@ void x11_init_LCD( void ) { /* init nibble_maps */ for ( int i = 0; i < 16; i++ ) nibble_maps[ i ] = - XCreateBitmapFromData( dpy, disp.win, ( char* )nibbles[ i ], 8, 2 ); + XCreateBitmapFromData( dpy, lcd.win, ( char* )nibbles[ i ], 8, 2 ); if ( !shm_flag ) return; - if ( disp.disp_image->bitmap_bit_order == MSBFirst ) { + if ( lcd.disp_image->bitmap_bit_order == MSBFirst ) { nibble_bitmap[ 0x0 ] = 0x00; /* ---- */ nibble_bitmap[ 0x1 ] = 0xc0; /* *--- */ nibble_bitmap[ 0x2 ] = 0x30; /* -*-- */ @@ -4877,7 +4867,7 @@ void x11_update_LCD( void ) { int val, line_pad, line_length; word_20 data_addr, data_addr_2; - if ( !disp.mapped ) { + if ( !mapped ) { refresh_icon(); return; } @@ -4885,24 +4875,24 @@ void x11_update_LCD( void ) { addr = display.disp_start; if ( shm_flag ) { data_addr = 0; - data_addr_2 = disp.disp_image->bytes_per_line; + data_addr_2 = lcd.disp_image->bytes_per_line; line_length = NIBBLES_PER_ROW; if ( display.offset > 3 ) line_length += 2; - line_pad = 2 * disp.disp_image->bytes_per_line - line_length; + line_pad = 2 * lcd.disp_image->bytes_per_line - line_length; addr_pad = display.nibs_per_line - line_length; for ( i = 0; i <= display.lines; i++ ) { for ( j = 0; j < line_length; j++ ) { val = read_nibble( addr++ ); - disp.disp_image->data[ data_addr++ ] = nibble_bitmap[ val ]; - disp.disp_image->data[ data_addr_2++ ] = + lcd.disp_image->data[ data_addr++ ] = nibble_bitmap[ val ]; + lcd.disp_image->data[ data_addr_2++ ] = nibble_bitmap[ val ]; } addr += addr_pad; data_addr += line_pad; data_addr_2 += line_pad; } - disp.display_update |= UPDATE_DISP; + lcd.display_update |= UPDATE_DISP; } else { if ( display.offset != old_offset ) { memset( @@ -4929,21 +4919,20 @@ void x11_update_LCD( void ) { addr = display.menu_start; if ( shm_flag ) { data_addr = 0; - data_addr_2 = disp.menu_image->bytes_per_line; - line_pad = - 2 * disp.menu_image->bytes_per_line - NIBBLES_PER_ROW; + data_addr_2 = lcd.menu_image->bytes_per_line; + line_pad = 2 * lcd.menu_image->bytes_per_line - NIBBLES_PER_ROW; for ( ; i < DISP_ROWS; i++ ) { for ( j = 0; j < NIBBLES_PER_ROW; j++ ) { val = read_nibble( addr++ ); - disp.menu_image->data[ data_addr++ ] = + lcd.menu_image->data[ data_addr++ ] = nibble_bitmap[ val ]; - disp.menu_image->data[ data_addr_2++ ] = + lcd.menu_image->data[ data_addr_2++ ] = nibble_bitmap[ val ]; } data_addr += line_pad; data_addr_2 += line_pad; } - disp.display_update |= UPDATE_MENU; + lcd.display_update |= UPDATE_MENU; } else { for ( ; i < DISP_ROWS; i++ ) { draw_row( addr, i ); @@ -4953,13 +4942,13 @@ void x11_update_LCD( void ) { } } else { if ( shm_flag ) { - memset( disp.disp_image->data, 0, - ( size_t )( disp.disp_image->bytes_per_line * - disp.disp_image->height ) ); - memset( disp.menu_image->data, 0, - ( size_t )( disp.menu_image->bytes_per_line * - disp.menu_image->height ) ); - disp.display_update = UPDATE_DISP | UPDATE_MENU; + memset( lcd.disp_image->data, 0, + ( size_t )( lcd.disp_image->bytes_per_line * + lcd.disp_image->height ) ); + memset( lcd.menu_image->data, 0, + ( size_t )( lcd.menu_image->bytes_per_line * + lcd.menu_image->height ) ); + lcd.display_update = UPDATE_DISP | UPDATE_MENU; } else { memset( disp_buf, 0xf0, sizeof( disp_buf ) ); for ( i = 0; i < 64; i++ ) { @@ -4970,12 +4959,12 @@ void x11_update_LCD( void ) { } } - if ( disp.display_update ) + if ( lcd.display_update ) refresh_display(); } void x11_refresh_LCD( void ) { - if ( disp.display_update ) + if ( lcd.display_update ) refresh_display(); } @@ -4993,12 +4982,11 @@ void x11_disp_draw_nibble( word_20 addr, word_4 val ) { if ( y < 0 || y > 63 ) return; if ( shm_flag ) { - shm_addr = ( 2 * y * disp.disp_image->bytes_per_line ) + x; - disp.disp_image->data[ shm_addr ] = nibble_bitmap[ val ]; - disp.disp_image - ->data[ shm_addr + disp.disp_image->bytes_per_line ] = + shm_addr = ( 2 * y * lcd.disp_image->bytes_per_line ) + x; + lcd.disp_image->data[ shm_addr ] = nibble_bitmap[ val ]; + lcd.disp_image->data[ shm_addr + lcd.disp_image->bytes_per_line ] = nibble_bitmap[ val ]; - disp.display_update |= UPDATE_DISP; + lcd.display_update |= UPDATE_DISP; } else { if ( val != disp_buf[ y ][ x ] ) { disp_buf[ y ][ x ] = val; @@ -5009,12 +4997,12 @@ void x11_disp_draw_nibble( word_20 addr, word_4 val ) { if ( shm_flag ) { shm_addr = x; for ( y = 0; y < display.lines; y++ ) { - disp.disp_image->data[ shm_addr ] = nibble_bitmap[ val ]; - shm_addr += disp.disp_image->bytes_per_line; - disp.disp_image->data[ shm_addr ] = nibble_bitmap[ val ]; - shm_addr += disp.disp_image->bytes_per_line; + lcd.disp_image->data[ shm_addr ] = nibble_bitmap[ val ]; + shm_addr += lcd.disp_image->bytes_per_line; + lcd.disp_image->data[ shm_addr ] = nibble_bitmap[ val ]; + shm_addr += lcd.disp_image->bytes_per_line; } - disp.display_update |= UPDATE_DISP; + lcd.display_update |= UPDATE_DISP; } else { for ( y = 0; y < display.lines; y++ ) { if ( val != disp_buf[ y ][ x ] ) { @@ -5034,12 +5022,12 @@ void x11_menu_draw_nibble( word_20 addr, word_4 val ) { offset = ( addr - display.menu_start ); if ( shm_flag ) { shm_addr = - 2 * ( offset / NIBBLES_PER_ROW ) * disp.menu_image->bytes_per_line + + 2 * ( offset / NIBBLES_PER_ROW ) * lcd.menu_image->bytes_per_line + ( offset % NIBBLES_PER_ROW ); - disp.menu_image->data[ shm_addr ] = nibble_bitmap[ val ]; - disp.menu_image->data[ shm_addr + disp.menu_image->bytes_per_line ] = + lcd.menu_image->data[ shm_addr ] = nibble_bitmap[ val ]; + lcd.menu_image->data[ shm_addr + lcd.menu_image->bytes_per_line ] = nibble_bitmap[ val ]; - disp.display_update |= UPDATE_MENU; + lcd.display_update |= UPDATE_MENU; } else { x = offset % NIBBLES_PER_ROW; y = display.lines + ( offset / NIBBLES_PER_ROW ) + 1; @@ -5061,11 +5049,11 @@ void x11_draw_annunc( void ) { for ( int i = 0; ann_tbl[ i ].bit; i++ ) { if ( ( ann_tbl[ i ].bit & val ) == ann_tbl[ i ].bit ) - XCopyPlane( dpy, ann_tbl[ i ].pixmap, disp.win, disp.gc, 0, 0, + XCopyPlane( dpy, ann_tbl[ i ].pixmap, lcd.win, lcd.gc, 0, 0, ann_tbl[ i ].width, ann_tbl[ i ].height, ann_tbl[ i ].x, ann_tbl[ i ].y, 1 ); else - XClearArea( dpy, disp.win, ann_tbl[ i ].x, ann_tbl[ i ].y, + XClearArea( dpy, lcd.win, ann_tbl[ i ].x, ann_tbl[ i ].y, ann_tbl[ i ].width, ann_tbl[ i ].height, False ); } refresh_icon(); From 2adba37461ee35e3401fd4b3f2f938c3404cc957 Mon Sep 17 00:00:00 2001 From: Gwenhael Le Moine Date: Wed, 20 Sep 2023 11:17:53 +0200 Subject: [PATCH 03/11] bring back configurable X "visual" with --x11-visual=XX --- dist/x48ng.man.1 | 22 ++--- src/runtime_options.c | 23 ++++-- src/runtime_options.h | 2 +- src/ui_x11.c | 185 ++++++++++++++++++++---------------------- 4 files changed, 119 insertions(+), 113 deletions(-) diff --git a/dist/x48ng.man.1 b/dist/x48ng.man.1 index 7105da7..597f0b7 100644 --- a/dist/x48ng.man.1 +++ b/dist/x48ng.man.1 @@ -29,7 +29,7 @@ .\" .\" $XFree86: xc/programs/xcalc/xcalc.man,v 1.5 2003/03/19 01:49:28 dawes Exp $ .\" -.de EX \"Begin example +.de EX \"Begin example .ne 5 .if n .sp 1 .if t .sp .5 @@ -91,23 +91,25 @@ where options include: .br \-T \-\-throttle try to emulate real speed (default: false) .br - \-\-sdl\-no\-chrome [SDL] only display the LCD (default: false) + \-\-sdl\-no\-chrome only display the LCD (default: false) .br - \-\-sdl\-fullscreen [SDL] make the UI fullscreen (default: false) + \-\-sdl\-fullscreen make the UI fullscreen (default: false) .br - \-\-x11\-netbook [X11] make the UI horizontal (default: false) + \-\-x11\-netbook make the UI horizontal (default: false) .br - \-\-x11\-mono [X11] make the UI monochrome (default: false) + \-\-x11\-mono make the UI monochrome (default: false) .br - \-\-x11\-gray [X11] make the UI grayscale (default: false) + \-\-x11\-gray make the UI grayscale (default: false) .br - \-\-x11\-small\-font= [X11] use as small font + \-\-x11\-visual= use visual (default: default), possible values: .br - \-\-x11\-medium\-font= [X11] use as medium font + \-\-x11\-small\-font= use as small font .br - \-\-x11\-large\-font= [X11] use as large font + \-\-x11\-medium\-font= use as medium font .br - \-\-x11\-connection\-font= [X11] use as connection font + \-\-x11\-large\-font= use as large font +.br + \-\-x11\-connection\-font= use as connection font .SH DESCRIPTION .I x48ng diff --git a/src/runtime_options.c b/src/runtime_options.c index 427ecfe..9f0437c 100644 --- a/src/runtime_options.c +++ b/src/runtime_options.c @@ -38,7 +38,10 @@ char* title = "x48ng"; char* geometry; /* char* iconGeom; */ /* char* iconName; */ -/* int x11_visual = -1; */ +char* x11_visual = "default"; +/* default | staticgray | staticcolor | truecolor | grayscale | + * pseudocolor | directcolor | 0xnn | nn + */ int mono = 0; int gray = 0; int monoIcon = 0; @@ -87,6 +90,7 @@ int parse_args( int argc, char* argv[] ) { { "x11-netbook", no_argument, &netbook, 1 }, { "x11-mono", no_argument, &mono, 1 }, { "x11-gray", no_argument, &gray, 1 }, + { "x11-visual", required_argument, NULL, 8110 }, { "x11-small-font", required_argument, NULL, 8111 }, { "x11-medium-font", required_argument, NULL, 8112 }, { "x11-large-font", required_argument, NULL, 8113 }, @@ -129,17 +133,21 @@ int parse_args( int argc, char* argv[] ) { "\t-i --initialize\t\t\tinitialize the content of \n" "\t-r --reset\t\t\tperform a reset on startup\n" "\t-T --throttle\t\t\ttry to emulate real speed (default: false)\n" - "\t --sdl-no-chrome\t\t[SDL only] only display the LCD (default: " + "\t --sdl-no-chrome\t\tonly display the LCD (default: " "false)\n" - "\t --sdl-fullscreen\t\t[SDL only] make the UI fullscreen " + "\t --sdl-fullscreen\t\tmake the UI fullscreen " "(default: " "false)\n" - "\t --x11-netbook\t\t[X11 only] make the UI horizontal (default: " + "\t --x11-netbook\t\tmake the UI horizontal (default: " "false)\n" - "\t --x11-mono\t\t\t[X11 only] make the UI monochrome (default: " + "\t --x11-mono\t\t\tmake the UI monochrome (default: " "false)\n" - "\t --x11-gray\t\t\t[X11 only] make the UI grayscale (default: " + "\t --x11-gray\t\t\tmake the UI grayscale (default: " "false)\n" + "\t --x11-visual=\tuse visual (default: " + "default), possible values: " + "\n" "\t --x11-small-font=\tuse as small " "font (default: %s)\n" "\t --x11-medium-font=\tuse as medium " @@ -183,6 +191,9 @@ int parse_args( int argc, char* argv[] ) { case 1015: serialLine = optarg; break; + case 8110: + x11_visual = optarg; + break; case 8111: smallFont = optarg; break; diff --git a/src/runtime_options.h b/src/runtime_options.h index 94d0da1..24ee7f2 100644 --- a/src/runtime_options.h +++ b/src/runtime_options.h @@ -36,7 +36,7 @@ extern char* title; extern char* geometry; /* extern char* iconGeom; */ /* extern char* iconName; */ -/* extern int x11_visual; */ +extern char* x11_visual; extern int mono; extern int gray; extern int monoIcon; diff --git a/src/ui_x11.c b/src/ui_x11.c index e0b6e5d..d60c5aa 100644 --- a/src/ui_x11.c +++ b/src/ui_x11.c @@ -1388,102 +1388,95 @@ static void fatal_exit( char* error, char* advice ) { exit( 1 ); } -/* static Visual* pick_visual_of_class( Display* dpy, int visual_class, */ -/* unsigned int* depth ) { */ -/* XVisualInfo vi_in, *vi_out; */ -/* int out_count; */ +inline Visual* pick_visual_of_class( Display* dpy, int visual_class, + unsigned int* depth ) { + XVisualInfo vi_in, *vi_out; + int out_count; -/* vi_in.class = visual_class; */ -/* vi_in.screen = DefaultScreen( dpy ); */ -/* vi_out = XGetVisualInfo( dpy, VisualClassMask | VisualScreenMask, &vi_in, - */ -/* &out_count ); */ -/* if ( vi_out ) { /\* choose the 'best' one, if multiple *\/ */ -/* int i, best; */ -/* Visual* visual; */ -/* for ( i = 0, best = 0; i < out_count; i++ ) */ -/* if ( vi_out[ i ].depth > vi_out[ best ].depth ) */ -/* best = i; */ -/* visual = vi_out[ best ].visual; */ -/* *depth = vi_out[ best ].depth; */ -/* XFree( ( char* )vi_out ); */ -/* return visual; */ -/* } else { */ -/* *depth = DefaultDepth( dpy, DefaultScreen( dpy ) ); */ -/* return DefaultVisual( dpy, DefaultScreen( dpy ) ); */ -/* } */ -/* } */ - -/* static Visual* id_to_visual( Display* dpy, int id, unsigned int* depth ) { */ -/* XVisualInfo vi_in, *vi_out; */ -/* int out_count; */ - -/* vi_in.screen = DefaultScreen( dpy ); */ -/* vi_in.visualid = id; */ -/* vi_out = XGetVisualInfo( dpy, VisualScreenMask | VisualIDMask, &vi_in, */ -/* &out_count ); */ -/* if ( vi_out ) { */ -/* Visual* v = vi_out[ 0 ].visual; */ -/* *depth = vi_out[ 0 ].depth; */ -/* XFree( ( char* )vi_out ); */ -/* return v; */ -/* } */ -/* return 0; */ -/* } */ - -static Visual* get_visual_resource( Display* dpy, char* name, char* class, - unsigned int* depth ) { - /* char c; */ - /* char *tmp, *s; */ - /* int vclass; */ - /* int id; */ - - /* s = get_string_resource( name, class ); */ - /* if ( s ) */ - /* for ( tmp = s; *tmp; tmp++ ) */ - /* if ( isupper( *tmp ) ) */ - /* *tmp = tolower( *tmp ); */ - - /* if ( !s || !strcmp( s, "default" ) ) */ - /* vclass = -1; */ - /* else if ( !strcmp( s, "staticgray" ) ) */ - /* vclass = StaticGray; */ - /* else if ( !strcmp( s, "staticcolor" ) ) */ - /* vclass = StaticColor; */ - /* else if ( !strcmp( s, "truecolor" ) ) */ - /* vclass = TrueColor; */ - /* else if ( !strcmp( s, "grayscale" ) ) */ - /* vclass = GrayScale; */ - /* else if ( !strcmp( s, "pseudocolor" ) ) */ - /* vclass = PseudoColor; */ - /* else if ( !strcmp( s, "directcolor" ) ) */ - /* vclass = DirectColor; */ - /* else if ( 1 == sscanf( s, " %d %c", &id, &c ) ) */ - /* vclass = -2; */ - /* else if ( 1 == sscanf( s, " 0x%x %c", &id, &c ) ) */ - /* vclass = -2; */ - /* else { */ - /* fprintf( stderr, "unrecognized visual \"%s\".\n", s ); */ - /* vclass = -1; */ - /* } */ - /* if ( s ) */ - /* free( s ); */ - - /* if ( vclass == -1 ) { */ - *depth = DefaultDepth( dpy, DefaultScreen( dpy ) ); - return DefaultVisual( dpy, DefaultScreen( dpy ) ); - /* } else if ( vclass == -2 ) { */ - /* Visual* v = id_to_visual( dpy, id, depth ); */ - /* if ( v ) */ - /* return v; */ - /* fprintf( stderr, "no visual with id 0x%x.\n", id ); */ - /* *depth = DefaultDepth( dpy, DefaultScreen( dpy ) ); */ - /* return DefaultVisual( dpy, DefaultScreen( dpy ) ); */ - /* } else */ - /* return pick_visual_of_class( dpy, vclass, depth ); */ + vi_in.class = visual_class; + vi_in.screen = DefaultScreen( dpy ); + vi_out = XGetVisualInfo( dpy, VisualClassMask | VisualScreenMask, &vi_in, + &out_count ); + if ( vi_out ) { /* choose the 'best' one, if multiple */ + int i, best; + Visual* visual; + for ( i = 0, best = 0; i < out_count; i++ ) + if ( vi_out[ i ].depth > vi_out[ best ].depth ) + best = i; + visual = vi_out[ best ].visual; + *depth = vi_out[ best ].depth; + XFree( ( char* )vi_out ); + return visual; + } else { + *depth = DefaultDepth( dpy, DefaultScreen( dpy ) ); + return DefaultVisual( dpy, DefaultScreen( dpy ) ); + } } -static XFontStruct* load_x11_font( Display* dpy, char* fontname ) { +inline Visual* id_to_visual( Display* dpy, int id, unsigned int* depth ) { + XVisualInfo vi_in, *vi_out; + int out_count; + + vi_in.screen = DefaultScreen( dpy ); + vi_in.visualid = id; + vi_out = XGetVisualInfo( dpy, VisualScreenMask | VisualIDMask, &vi_in, + &out_count ); + if ( vi_out ) { + Visual* v = vi_out[ 0 ].visual; + *depth = vi_out[ 0 ].depth; + XFree( ( char* )vi_out ); + return v; + } + return 0; +} + +Visual* get_visual_resource( Display* dpy, unsigned int* depth ) { + char c; + int vclass; + int id; + + if ( !x11_visual || !strcmp( x11_visual, "default" ) ) + vclass = -1; + else if ( !strcmp( x11_visual, "staticgray" ) ) + vclass = StaticGray; + else if ( !strcmp( x11_visual, "staticcolor" ) ) + vclass = StaticColor; + else if ( !strcmp( x11_visual, "truecolor" ) ) + vclass = TrueColor; + else if ( !strcmp( x11_visual, "grayscale" ) ) + vclass = GrayScale; + else if ( !strcmp( x11_visual, "pseudocolor" ) ) + vclass = PseudoColor; + else if ( !strcmp( x11_visual, "directcolor" ) ) + vclass = DirectColor; + else if ( 1 == sscanf( x11_visual, " %d %c", &id, &c ) ) + vclass = -2; + else if ( 1 == sscanf( x11_visual, " 0x%x %c", &id, &c ) ) + vclass = -2; + else { + fprintf( stderr, "unrecognized visual \"%s\".\n", x11_visual ); + vclass = -1; + } + + if ( vclass == -1 ) { + *depth = DefaultDepth( dpy, DefaultScreen( dpy ) ); + + return DefaultVisual( dpy, DefaultScreen( dpy ) ); + } else if ( vclass == -2 ) { + Visual* v = id_to_visual( dpy, id, depth ); + if ( v ) + return v; + + fprintf( stderr, "no visual with id 0x%x.\n", id ); + + *depth = DefaultDepth( dpy, DefaultScreen( dpy ) ); + + return DefaultVisual( dpy, DefaultScreen( dpy ) ); + } else + return pick_visual_of_class( dpy, vclass, depth ); +} + +XFontStruct* load_x11_font( Display* dpy, char* fontname ) { XFontStruct* f = ( XFontStruct* )0; f = XLoadQueryFont( dpy, fontname ); @@ -2938,7 +2931,7 @@ int handle_xerror( Display* the_dpy, XErrorEvent* eev ) { return 0; } -void CreateDispWindow( void ) { +void CreateLCDWindow( void ) { XSetWindowAttributes xswa; XGCValues val; unsigned long gc_mask; @@ -3210,7 +3203,7 @@ int CreateWindows( int argc, char** argv ) { } class = InputOutput; - visual = get_visual_resource( dpy, "visual", "Visual", &depth ); + visual = get_visual_resource( dpy, &depth ); if ( visual != DefaultVisual( dpy, screen ) ) { if ( visual->class == DirectColor ) cmap = XCreateColormap( dpy, RootWindow( dpy, screen ), visual, @@ -3439,7 +3432,7 @@ int CreateWindows( int argc, char** argv ) { /* * create the display */ - CreateDispWindow(); + CreateLCDWindow(); /* * create the keypad From 2a355bbd27d34e5ee0ab0927fbd8f7ec1564e8d6 Mon Sep 17 00:00:00 2001 From: Gwenhael Le Moine Date: Wed, 20 Sep 2023 11:19:11 +0200 Subject: [PATCH 04/11] 0.25.1 --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index a461575..9319c42 100644 --- a/Makefile +++ b/Makefile @@ -2,7 +2,7 @@ VERSION_MAJOR = 0 VERSION_MINOR = 25 -PATCHLEVEL = 0 +PATCHLEVEL = 1 MAKEFLAGS +=-j$(NUM_CORES) -l$(NUM_CORES) From 0f5b59afb0d0aa950068eac467058ebd77a82d66 Mon Sep 17 00:00:00 2001 From: Gwenhael Le Moine Date: Wed, 20 Sep 2023 12:24:23 +0200 Subject: [PATCH 05/11] add missing state variables from verbose output --- src/runtime_options.c | 36 +++++++++++++++++++++++++++++++++++- 1 file changed, 35 insertions(+), 1 deletion(-) diff --git a/src/runtime_options.c b/src/runtime_options.c index 9f0437c..84e9662 100644 --- a/src/runtime_options.c +++ b/src/runtime_options.c @@ -257,13 +257,47 @@ int parse_args( int argc, char* argv[] ) { fprintf( stderr, "verbose = %i\n", verbose ); fprintf( stderr, "useTerminal = %i\n", useTerminal ); fprintf( stderr, "useSerial = %i\n", useSerial ); + fprintf( stderr, "useDebugger = %i\n", useDebugger ); fprintf( stderr, "throttle = %i\n", throttle ); fprintf( stderr, "initialize = %i\n", initialize ); fprintf( stderr, "resetOnStartup = %i\n", resetOnStartup ); + fprintf( stderr, "frontend_type = " ); + switch ( frontend_type ) { + case FRONTEND_X11: + fprintf( stderr, "x11\n" ); + break; + case FRONTEND_SDL: + fprintf( stderr, "sdl\n" ); + break; + case FRONTEND_TEXT: + fprintf( stderr, "text\n" ); + break; + default: + fprintf( stderr, "???\n" ); + break; + } fprintf( stderr, "serialLine = %s\n", serialLine ); - fprintf( stderr, "romFileName = %s\n", romFileName ); fprintf( stderr, "homeDirectory = %s\n", homeDirectory ); + fprintf( stderr, "romFileName = %s\n", romFileName ); + fprintf( stderr, "ramFileName = %s\n", ramFileName ); + fprintf( stderr, "stateFileName = %s\n", stateFileName ); + fprintf( stderr, "port1FileName = %s\n", port1FileName ); + fprintf( stderr, "port2FileName = %s\n", port2FileName ); + + fprintf( stderr, "netbook = %i\n", netbook ); + fprintf( stderr, "mono = %i\n", mono ); + fprintf( stderr, "gray = %i\n", gray ); + fprintf( stderr, "monoIcon = %i\n", monoIcon ); + fprintf( stderr, "iconic = %i\n", iconic ); + fprintf( stderr, "xrm = %i\n", xrm ); + + fprintf( stderr, "geometry = %s\n", geometry ); + fprintf( stderr, "x11_visual = %s\n", x11_visual ); + fprintf( stderr, "smallFont = %s\n", smallFont ); + fprintf( stderr, "mediumFont = %s\n", mediumFont ); + fprintf( stderr, "largeFont = %s\n", largeFont ); + fprintf( stderr, "connFont = %s\n", connFont ); } return ( optind ); From f515cc09f74f5ebaf8fb4437b776137d853a0c96 Mon Sep 17 00:00:00 2001 From: Gwenhael Le Moine Date: Wed, 20 Sep 2023 13:33:16 +0200 Subject: [PATCH 06/11] initialize automatically if needed ans conditions are met --- src/emu_init.c | 38 ++++----------------- src/runtime_options.c | 77 +++++++++++++++++++++++++++++++++++++++++++ src/runtime_options.h | 1 + 3 files changed, 84 insertions(+), 32 deletions(-) diff --git a/src/emu_init.c b/src/emu_init.c index 10bf9e5..539cd7d 100644 --- a/src/emu_init.c +++ b/src/emu_init.c @@ -1,5 +1,4 @@ #include -#include #include #include #include @@ -27,33 +26,6 @@ long port2_size; long port2_mask; short port2_is_ram; -void get_home_directory( char* path ) { - char* p; - struct passwd* pwd; - - if ( homeDirectory[ 0 ] == '/' ) - strcpy( path, homeDirectory ); - else { - p = getenv( "HOME" ); - if ( p ) { - strcpy( path, p ); - strcat( path, "/" ); - } else { - pwd = getpwuid( getuid() ); - if ( pwd ) { - strcpy( path, pwd->pw_dir ); - strcat( path, "/" ); - } else { - if ( verbose ) - fprintf( stderr, "can\'t figure out your home directory, " - "trying /tmp\n" ); - strcpy( path, "/tmp" ); - } - } - strcat( path, homeDirectory ); - } -} - int read_rom( const char* fname ) { int ram_size; @@ -105,8 +77,6 @@ void saturn_config_init( void ) { } void init_saturn( void ) { - int i; - memset( &saturn, 0, sizeof( saturn ) - 4 * sizeof( unsigned char* ) ); saturn.PC = 0x00000; saturn.magic = X48_MAGIC; @@ -124,7 +94,7 @@ void init_saturn( void ) { saturn.timer1 = 0; saturn.timer2 = 0x2000; saturn.bank_switch = 0; - for ( i = 0; i < NR_MCTL; i++ ) { + for ( int i = 0; i < NR_MCTL; i++ ) { if ( i == 0 ) saturn.mem_cntl[ i ].unconfigured = 1; else if ( i == 5 ) @@ -138,14 +108,18 @@ void init_saturn( void ) { } int init_emulator( void ) { + /* If not forced to initialize and files are readble => let's go */ if ( !initialize && read_files() ) { if ( resetOnStartup ) saturn.PC = 0x00000; return 0; } - init_saturn(); + /* if forced initialize or files were not readble => initialize */ + if ( verbose ) + fprintf( stderr, "initialization of %s\n", homeDirectory ); + init_saturn(); if ( !read_rom( romFileName ) ) exit( 1 ); diff --git a/src/runtime_options.c b/src/runtime_options.c index 84e9662..cf94401 100644 --- a/src/runtime_options.c +++ b/src/runtime_options.c @@ -1,6 +1,9 @@ #include #include #include +#include +#include +#include #include @@ -52,6 +55,33 @@ char* mediumFont = "-*-fixed-bold-r-normal-*-15-*-*-*-*-*-iso8859-1"; char* largeFont = "-*-fixed-medium-r-normal-*-20-*-*-*-*-*-iso8859-1"; char* connFont = "-*-fixed-medium-r-normal-*-12-*-*-*-*-*-iso8859-1"; +void get_home_directory( char* path ) { + char* p; + struct passwd* pwd; + + if ( homeDirectory[ 0 ] == '/' ) + strcpy( path, homeDirectory ); + else { + p = getenv( "HOME" ); + if ( p ) { + strcpy( path, p ); + strcat( path, "/" ); + } else { + pwd = getpwuid( getuid() ); + if ( pwd ) { + strcpy( path, pwd->pw_dir ); + strcat( path, "/" ); + } else { + if ( verbose ) + fprintf( stderr, "can\'t figure out your home directory, " + "trying /tmp\n" ); + strcpy( path, "/tmp" ); + } + } + strcat( path, homeDirectory ); + } +} + int parse_args( int argc, char* argv[] ) { int option_index; int c = '?'; @@ -300,5 +330,52 @@ int parse_args( int argc, char* argv[] ) { fprintf( stderr, "connFont = %s\n", connFont ); } + /* check that homeDirectory exists, otherwise initialize */ + char config_dir[ 1024 ]; + char rom_filename[ 1024 ]; + char config_filename[ 1024 ]; + struct stat sb; + + get_home_directory( config_dir ); + if ( romFileName[ 0 ] == '/' ) + strcpy( rom_filename, "" ); + else + strcpy( rom_filename, config_dir ); + strcat( rom_filename, romFileName ); + + if ( stat( config_dir, &sb ) == 0 && S_ISDIR( sb.st_mode ) && + stat( rom_filename, &sb ) == 0 ) { + if ( verbose ) + fprintf( stderr, "%s exists\n", config_dir ); + + /* a config_dir exists with a romFileName in it. */ + /* we can initialize if necessary */ + if ( !initialize ) { + /* Not forced to initialize but does stateFileName exist? */ + if ( stateFileName[ 0 ] == '/' ) + strcpy( config_filename, "" ); + else + strcpy( config_filename, config_dir ); + strcat( config_filename, stateFileName ); + /* if not then initialize */ + initialize = stat( config_filename, &sb ) == 0 ? 0 : 1; + + /* Not forced to initialize but does ramFileName exist? */ + if ( ramFileName[ 0 ] == '/' ) + strcpy( config_filename, "" ); + else + strcpy( config_filename, config_dir ); + strcat( config_filename, ramFileName ); + /* if not then initialize */ + initialize = stat( config_filename, &sb ) == 0 ? 0 : 1; + } + } else { + if ( mkdir( config_dir, 0755 ) == 0 ) + fprintf( stderr, "Created %s, please copy a rom in it.\n", + config_dir ); + + exit( 1 ); + } + return ( optind ); } diff --git a/src/runtime_options.h b/src/runtime_options.h index 24ee7f2..3eb6e63 100644 --- a/src/runtime_options.h +++ b/src/runtime_options.h @@ -50,6 +50,7 @@ extern char* connFont; /*************/ /* functions */ /*************/ +extern void get_home_directory( char* path ); extern int parse_args( int argc, char* argv[] ); #endif /* !_OPTIONS_H */ From d83c6c4302760c46197f7c70722a64cbfcaa388e Mon Sep 17 00:00:00 2001 From: Gwenhael Le Moine Date: Wed, 20 Sep 2023 16:05:42 +0200 Subject: [PATCH 07/11] normalize all filenames to absolute at init --- dist/x48ng.man.1 | 10 +-- src/emu_init.c | 200 +++++++++++++++++------------------------- src/runtime_options.c | 151 ++++++++++++++++--------------- src/runtime_options.h | 12 ++- src/ui_sdl.c | 2 +- 5 files changed, 175 insertions(+), 200 deletions(-) diff --git a/dist/x48ng.man.1 b/dist/x48ng.man.1 index 597f0b7..62dd489 100644 --- a/dist/x48ng.man.1 +++ b/dist/x48ng.man.1 @@ -57,15 +57,15 @@ where options include: .br \-\-config\-dir= use as x48ng's home (default: ~/.x48ng/) .br - \-\-rom\-file= use (relative to ) as ROM (default: rom) + \-\-rom= use (absolute or relative to ) as ROM (default: rom) .br - \-\-ram\-file= use (relative to ) as RAM (default: ram) + \-\-ram= use (absolute or relative to ) as RAM (default: ram) .br - \-\-state\-file= use (relative to ) as STATE (default: hp48) + \-\-state= use (absolute or relative to ) as STATE (default: hp48) .br - \-\-port1\-file= use (relative to ) as PORT1 (default: port1) + \-\-port1= use (absolute or relative to ) as PORT1 (default: port1) .br - \-\-port2\-file= use (relative to ) as PORT2 (default: port2) + \-\-port2= use (absolute or relative to ) as PORT2 (default: port2) .br \-\-serial\-line= use as serial device default: /dev/ttyS0) .br diff --git a/src/emu_init.c b/src/emu_init.c index 539cd7d..973d4cf 100644 --- a/src/emu_init.c +++ b/src/emu_init.c @@ -117,10 +117,10 @@ int init_emulator( void ) { /* if forced initialize or files were not readble => initialize */ if ( verbose ) - fprintf( stderr, "initialization of %s\n", homeDirectory ); + fprintf( stderr, "initialization of %s\n", normalized_config_path ); init_saturn(); - if ( !read_rom( romFileName ) ) + if ( !read_rom( normalized_rom_path ) ) exit( 1 ); return 0; @@ -391,7 +391,7 @@ int read_mem_file( char* name, word_4* mem, int size ) { /* * size is same as memory size, old version file */ - if ( fread( mem, 1, ( size_t )size, fp ) != size ) { + if ( fread( mem, 1, ( size_t )size, fp ) != ( unsigned long )size ) { if ( verbose ) fprintf( stderr, "can\'t read %s\n", name ); fclose( fp ); @@ -422,7 +422,8 @@ int read_mem_file( char* name, word_4* mem, int size ) { mem[ j++ ] = ( word_4 )( ( ( int )byte >> 4 ) & 0xf ); } } else { - if ( fread( tmp_mem, 1, ( size_t )size / 2, fp ) != size / 2 ) { + if ( fread( tmp_mem, 1, ( size_t )size / 2, fp ) != + ( unsigned long )( size / 2 ) ) { if ( verbose ) fprintf( stderr, "can\'t read %s\n", name ); fclose( fp ); @@ -448,45 +449,30 @@ int read_mem_file( char* name, word_4* mem, int size ) { } int read_files( void ) { - char config_dir[ 1024 ]; - char fnam[ 1024 ]; unsigned long v1, v2; int i, read_version; int ram_size; struct stat st; FILE* fp; - get_home_directory( config_dir ); - strcat( config_dir, "/" ); - /*************************************************/ /* 1. read ROM from ~/.x48ng/rom into saturn.rom */ /*************************************************/ saturn.rom = ( word_4* )NULL; - if ( romFileName[ 0 ] == '/' ) - strcpy( fnam, "" ); - else - strcpy( fnam, config_dir ); - strcat( fnam, romFileName ); - if ( !read_rom_file( fnam, &saturn.rom, &rom_size ) ) + if ( !read_rom_file( normalized_rom_path, &saturn.rom, &rom_size ) ) return 0; if ( verbose ) - printf( "read %s\n", fnam ); + printf( "read %s\n", normalized_rom_path ); rom_is_new = 0; /**************************************************/ /* 2. read saved state from ~/.x48ng/hp48 into fp */ /**************************************************/ - if ( stateFileName[ 0 ] == '/' ) - strcpy( fnam, "" ); - else - strcpy( fnam, config_dir ); - strcat( fnam, stateFileName ); - if ( NULL == ( fp = fopen( fnam, "r" ) ) ) { + if ( NULL == ( fp = fopen( normalized_state_path, "r" ) ) ) { if ( verbose ) - fprintf( stderr, "can\'t open %s\n", fnam ); + fprintf( stderr, "can\'t open %s\n", normalized_state_path ); return 0; } @@ -529,10 +515,11 @@ int read_files( void ) { */ if ( !read_state_file( fp ) ) { if ( verbose ) - fprintf( stderr, "can\'t handle %s\n", fnam ); + fprintf( stderr, "can\'t handle %s\n", + normalized_state_path ); init_saturn(); } else if ( verbose ) - printf( "read %s\n", fnam ); + printf( "read %s\n", normalized_state_path ); } } fclose( fp ); @@ -553,17 +540,12 @@ int read_files( void ) { /*************************************************/ /* 3. read RAM from ~/.x48ng/ram into saturn.ram */ /*************************************************/ - if ( ramFileName[ 0 ] == '/' ) - strcpy( fnam, "" ); - else - strcpy( fnam, config_dir ); - strcat( fnam, ramFileName ); - if ( ( fp = fopen( fnam, "r" ) ) == NULL ) { + if ( ( fp = fopen( normalized_ram_path, "r" ) ) == NULL ) { if ( verbose ) - fprintf( stderr, "can\'t open %s\n", fnam ); + fprintf( stderr, "can\'t open %s\n", normalized_ram_path ); return 0; } - if ( !read_mem_file( fnam, saturn.ram, ram_size ) ) + if ( !read_mem_file( normalized_ram_path, saturn.ram, ram_size ) ) return 0; /**************************************/ @@ -579,18 +561,14 @@ int read_files( void ) { port1_is_ram = 0; saturn.port1 = ( unsigned char* )0; - if ( port1FileName[ 0 ] == '/' ) - strcpy( fnam, "" ); - else - strcpy( fnam, config_dir ); - strcat( fnam, port1FileName ); - if ( stat( fnam, &st ) >= 0 ) { + if ( stat( normalized_port1_path, &st ) >= 0 ) { port1_size = 2 * st.st_size; if ( ( port1_size == 0x10000 ) || ( port1_size == 0x40000 ) ) { if ( NULL == ( saturn.port1 = ( word_4* )malloc( port1_size ) ) ) { if ( verbose ) fprintf( stderr, "can\'t malloc PORT1[%ld]\n", port1_size ); - } else if ( !read_mem_file( fnam, saturn.port1, port1_size ) ) { + } else if ( !read_mem_file( normalized_port1_path, saturn.port1, + port1_size ) ) { port1_size = 0; port1_is_ram = 0; } else { @@ -616,12 +594,7 @@ int read_files( void ) { port2_is_ram = 0; saturn.port2 = ( unsigned char* )0; - if ( port2FileName[ 0 ] == '/' ) - strcpy( fnam, "" ); - else - strcpy( fnam, config_dir ); - strcat( fnam, port2FileName ); - if ( stat( fnam, &st ) >= 0 ) { + if ( stat( normalized_port2_path, &st ) >= 0 ) { port2_size = 2 * st.st_size; if ( ( opt_gx && ( ( port2_size % 0x40000 ) == 0 ) ) || ( !opt_gx && @@ -629,7 +602,8 @@ int read_files( void ) { if ( NULL == ( saturn.port2 = ( word_4* )malloc( port2_size ) ) ) { if ( verbose ) fprintf( stderr, "can\'t malloc PORT2[%ld]\n", port2_size ); - } else if ( !read_mem_file( fnam, saturn.port2, port2_size ) ) { + } else if ( !read_mem_file( normalized_port2_path, saturn.port2, + port2_size ) ) { port2_size = 0; port2_is_ram = 0; } else { @@ -773,54 +747,13 @@ int write_mem_file( char* name, word_4* mem, int size ) { return 1; } -int write_files( void ) { - char config_dir[ 1024 ]; - char fnam[ 1024 ]; - struct stat st; - int i, make_dir; - int ram_size; +int write_state_file( char* filename ) { + int i; FILE* fp; - make_dir = 0; - get_home_directory( config_dir ); - - if ( stat( config_dir, &st ) == -1 ) { - if ( errno == ENOENT ) { - make_dir = 1; - } else { - if ( verbose ) - fprintf( stderr, "can\'t stat %s, saving to /tmp\n", - config_dir ); - strcpy( config_dir, "/tmp" ); - } - } else { - if ( !S_ISDIR( st.st_mode ) ) { - if ( verbose ) - fprintf( stderr, "%s is no directory, saving to /tmp\n", - config_dir ); - strcpy( config_dir, "/tmp" ); - } - } - - if ( make_dir ) { - if ( mkdir( config_dir, 0777 ) == -1 ) { - if ( verbose ) - fprintf( stderr, "can\'t mkdir %s, saving to /tmp\n", - config_dir ); - strcpy( config_dir, "/tmp" ); - } - } - - strcat( config_dir, "/" ); - - if ( stateFileName[ 0 ] == '/' ) - strcpy( fnam, "" ); - else - strcpy( fnam, config_dir ); - strcat( fnam, stateFileName ); - if ( ( fp = fopen( fnam, "w" ) ) == NULL ) { + if ( ( fp = fopen( filename, "w" ) ) == NULL ) { if ( verbose ) - fprintf( stderr, "can\'t open %s, no saving done\n", fnam ); + fprintf( stderr, "can\'t open %s, no saving done\n", filename ); return 0; } @@ -918,45 +851,72 @@ int write_files( void ) { } fclose( fp ); if ( verbose ) - printf( "wrote %s\n", fnam ); + printf( "wrote %s\n", filename ); - if ( rom_is_new ) { - strcpy( fnam, config_dir ); - strcat( fnam, romFileName ); - if ( !write_mem_file( fnam, saturn.rom, rom_size ) ) - return 0; + return 1; +} + +int write_files( void ) { + struct stat st; + int make_dir = 0; + int ram_size = opt_gx ? RAM_SIZE_GX : RAM_SIZE_SX; + + if ( stat( normalized_config_path, &st ) == -1 ) { + if ( errno == ENOENT ) { + make_dir = 1; + } else { + if ( verbose ) + fprintf( stderr, "can\'t stat %s, saving to /tmp\n", + normalized_config_path ); + strcpy( normalized_config_path, "/tmp" ); + } + } else { + if ( !S_ISDIR( st.st_mode ) ) { + if ( verbose ) + fprintf( stderr, "%s is no directory, saving to /tmp\n", + normalized_config_path ); + strcpy( normalized_config_path, "/tmp" ); + } } - if ( opt_gx ) - ram_size = RAM_SIZE_GX; - else - ram_size = RAM_SIZE_SX; + if ( make_dir ) { + if ( mkdir( normalized_config_path, 0777 ) == -1 ) { + if ( verbose ) + fprintf( stderr, "can\'t mkdir %s, saving to /tmp\n", + normalized_config_path ); + strcpy( normalized_config_path, "/tmp" ); + } + } - if ( ramFileName[ 0 ] == '/' ) - strcpy( fnam, "" ); - else - strcpy( fnam, config_dir ); - strcat( fnam, ramFileName ); - if ( !write_mem_file( fnam, saturn.ram, ram_size ) ) + if ( !write_state_file( normalized_state_path ) ) + return 0; + + rom_is_new = make_dir; + if ( rom_is_new ) { + char new_rom_path[ MAX_LENGTH_FILENAME ]; + + strcpy( new_rom_path, normalized_config_path ); + strcat( new_rom_path, "rom" ); + + if ( !write_mem_file( new_rom_path, saturn.rom, rom_size ) ) + return 0; + + if ( verbose ) + printf( "wrote %s\n", new_rom_path ); + } + + if ( !write_mem_file( normalized_ram_path, saturn.ram, ram_size ) ) return 0; if ( ( port1_size > 0 ) && port1_is_ram ) { - if ( port1FileName[ 0 ] == '/' ) - strcpy( fnam, "" ); - else - strcpy( fnam, config_dir ); - strcat( fnam, port1FileName ); - if ( !write_mem_file( fnam, saturn.port1, port1_size ) ) + if ( !write_mem_file( normalized_port1_path, saturn.port1, + port1_size ) ) return 0; } if ( ( port2_size > 0 ) && port2_is_ram ) { - if ( port2FileName[ 0 ] == '/' ) - strcpy( fnam, "" ); - else - strcpy( fnam, config_dir ); - strcat( fnam, port2FileName ); - if ( !write_mem_file( fnam, saturn.port2, port2_size ) ) + if ( !write_mem_file( normalized_port2_path, saturn.port2, + port2_size ) ) return 0; } diff --git a/src/runtime_options.c b/src/runtime_options.c index cf94401..cfcfc1a 100644 --- a/src/runtime_options.c +++ b/src/runtime_options.c @@ -20,8 +20,8 @@ int initialize = 0; int resetOnStartup = 0; char* serialLine = "/dev/ttyS0"; -char* homeDirectory = ".x48ng"; +char* configDir = ".x48ng"; char* romFileName = "rom"; char* ramFileName = "ram"; char* stateFileName = "hp48"; @@ -55,31 +55,72 @@ char* mediumFont = "-*-fixed-bold-r-normal-*-15-*-*-*-*-*-iso8859-1"; char* largeFont = "-*-fixed-medium-r-normal-*-20-*-*-*-*-*-iso8859-1"; char* connFont = "-*-fixed-medium-r-normal-*-12-*-*-*-*-*-iso8859-1"; -void get_home_directory( char* path ) { - char* p; +char normalized_config_path[ MAX_LENGTH_FILENAME ]; +char normalized_rom_path[ MAX_LENGTH_FILENAME ]; +char normalized_ram_path[ MAX_LENGTH_FILENAME ]; +char normalized_state_path[ MAX_LENGTH_FILENAME ]; +char normalized_port1_path[ MAX_LENGTH_FILENAME ]; +char normalized_port2_path[ MAX_LENGTH_FILENAME ]; + +void get_absolute_config_dir( char* source, char* dest ) { + char* home; struct passwd* pwd; - if ( homeDirectory[ 0 ] == '/' ) - strcpy( path, homeDirectory ); - else { - p = getenv( "HOME" ); - if ( p ) { - strcpy( path, p ); - strcat( path, "/" ); + if ( source[ 0 ] != '/' ) { + home = getenv( "HOME" ); + if ( home ) { + strcpy( dest, home ); + strcat( dest, "/" ); } else { pwd = getpwuid( getuid() ); if ( pwd ) { - strcpy( path, pwd->pw_dir ); - strcat( path, "/" ); + strcpy( dest, pwd->pw_dir ); + strcat( dest, "/" ); } else { if ( verbose ) fprintf( stderr, "can\'t figure out your home directory, " "trying /tmp\n" ); - strcpy( path, "/tmp" ); + strcpy( dest, "/tmp" ); } } - strcat( path, homeDirectory ); } + strcat( dest, source ); + if ( dest[ strlen( dest ) ] != '/' ) + strcat( dest, "/" ); +} + +static inline void normalize_filenames( void ) { + get_absolute_config_dir( configDir, normalized_config_path ); + + if ( romFileName[ 0 ] == '/' ) + strcpy( normalized_rom_path, "" ); + else + strcpy( normalized_rom_path, normalized_config_path ); + strcat( normalized_rom_path, romFileName ); + + if ( ramFileName[ 0 ] == '/' ) + strcpy( normalized_ram_path, "" ); + else + strcpy( normalized_ram_path, normalized_config_path ); + strcat( normalized_ram_path, ramFileName ); + + if ( stateFileName[ 0 ] == '/' ) + strcpy( normalized_state_path, "" ); + else + strcpy( normalized_state_path, normalized_config_path ); + strcat( normalized_state_path, stateFileName ); + + if ( port1FileName[ 0 ] == '/' ) + strcpy( normalized_port1_path, "" ); + else + strcpy( normalized_port1_path, normalized_config_path ); + strcat( normalized_port1_path, port1FileName ); + + if ( port2FileName[ 0 ] == '/' ) + strcpy( normalized_port2_path, "" ); + else + strcpy( normalized_port2_path, normalized_config_path ); + strcat( normalized_port2_path, port2FileName ); } int parse_args( int argc, char* argv[] ) { @@ -89,11 +130,11 @@ int parse_args( int argc, char* argv[] ) { char* optstring = "c:S:u:hvVtsirT"; static struct option long_options[] = { { "config-dir", required_argument, NULL, 1000 }, - { "rom-file", required_argument, NULL, 1010 }, - { "ram-file", required_argument, NULL, 1011 }, - { "state-file", required_argument, NULL, 1012 }, - { "port1-file", required_argument, NULL, 1013 }, - { "port2-file", required_argument, NULL, 1014 }, + { "rom", required_argument, NULL, 1010 }, + { "ram", required_argument, NULL, 1011 }, + { "state", required_argument, NULL, 1012 }, + { "port1", required_argument, NULL, 1013 }, + { "port2", required_argument, NULL, 1014 }, { "serial-line", required_argument, NULL, 1015 }, @@ -137,15 +178,15 @@ int parse_args( int argc, char* argv[] ) { "\t-v --version\t\t\tshow version\n" "\t --config-dir=\t\tuse as x48ng's home (default: " "~/.x48ng/)\n" - "\t --rom-file=\tuse (absolute or relative to " + "\t --rom=\tuse (absolute or relative to " ") as ROM (default: rom)\n" - "\t --ram-file=\tuse (absolute or relative to " + "\t --ram=\tuse (absolute or relative to " ") as RAM (default: ram)\n" - "\t --state-file=\tuse (absolute or relative " + "\t --state=\tuse (absolute or relative " "to ) as STATE (default: hp48)\n" - "\t --port1-file=\tuse (absolute or relative " + "\t --port1=\tuse (absolute or relative " "to ) as PORT1 (default: port1)\n" - "\t --port2-file=\tuse (absolute or relative " + "\t --port2=\tuse (absolute or relative " "to ) as PORT2 (default: port2)\n" "\t --serial-line=\t\tuse as serial device default: " "%s)\n" @@ -201,7 +242,7 @@ int parse_args( int argc, char* argv[] ) { exit( 0 ); break; case 1000: - homeDirectory = optarg; + configDir = optarg; break; case 1010: romFileName = optarg; @@ -283,6 +324,8 @@ int parse_args( int argc, char* argv[] ) { fprintf( stderr, "\n" ); } + normalize_filenames(); + if ( verbose ) { fprintf( stderr, "verbose = %i\n", verbose ); fprintf( stderr, "useTerminal = %i\n", useTerminal ); @@ -308,7 +351,7 @@ int parse_args( int argc, char* argv[] ) { } fprintf( stderr, "serialLine = %s\n", serialLine ); - fprintf( stderr, "homeDirectory = %s\n", homeDirectory ); + fprintf( stderr, "configDir = %s\n", configDir ); fprintf( stderr, "romFileName = %s\n", romFileName ); fprintf( stderr, "ramFileName = %s\n", ramFileName ); fprintf( stderr, "stateFileName = %s\n", stateFileName ); @@ -328,53 +371,17 @@ int parse_args( int argc, char* argv[] ) { fprintf( stderr, "mediumFont = %s\n", mediumFont ); fprintf( stderr, "largeFont = %s\n", largeFont ); fprintf( stderr, "connFont = %s\n", connFont ); - } - /* check that homeDirectory exists, otherwise initialize */ - char config_dir[ 1024 ]; - char rom_filename[ 1024 ]; - char config_filename[ 1024 ]; - struct stat sb; - - get_home_directory( config_dir ); - if ( romFileName[ 0 ] == '/' ) - strcpy( rom_filename, "" ); - else - strcpy( rom_filename, config_dir ); - strcat( rom_filename, romFileName ); - - if ( stat( config_dir, &sb ) == 0 && S_ISDIR( sb.st_mode ) && - stat( rom_filename, &sb ) == 0 ) { - if ( verbose ) - fprintf( stderr, "%s exists\n", config_dir ); - - /* a config_dir exists with a romFileName in it. */ - /* we can initialize if necessary */ - if ( !initialize ) { - /* Not forced to initialize but does stateFileName exist? */ - if ( stateFileName[ 0 ] == '/' ) - strcpy( config_filename, "" ); - else - strcpy( config_filename, config_dir ); - strcat( config_filename, stateFileName ); - /* if not then initialize */ - initialize = stat( config_filename, &sb ) == 0 ? 0 : 1; - - /* Not forced to initialize but does ramFileName exist? */ - if ( ramFileName[ 0 ] == '/' ) - strcpy( config_filename, "" ); - else - strcpy( config_filename, config_dir ); - strcat( config_filename, ramFileName ); - /* if not then initialize */ - initialize = stat( config_filename, &sb ) == 0 ? 0 : 1; - } - } else { - if ( mkdir( config_dir, 0755 ) == 0 ) - fprintf( stderr, "Created %s, please copy a rom in it.\n", - config_dir ); - - exit( 1 ); + fprintf( stderr, "normalized_config_path = %s\n", + normalized_config_path ); + fprintf( stderr, "normalized_rom_path = %s\n", normalized_rom_path ); + fprintf( stderr, "normalized_ram_path = %s\n", normalized_ram_path ); + fprintf( stderr, "normalized_state_path = %s\n", + normalized_state_path ); + fprintf( stderr, "normalized_port1_path = %s\n", + normalized_port1_path ); + fprintf( stderr, "normalized_port2_path = %s\n", + normalized_port2_path ); } return ( optind ); diff --git a/src/runtime_options.h b/src/runtime_options.h index 3eb6e63..fd31931 100644 --- a/src/runtime_options.h +++ b/src/runtime_options.h @@ -17,8 +17,8 @@ extern int resetOnStartup; extern int frontend_type; extern char* serialLine; -extern char* homeDirectory; +extern char* configDir; extern char* romFileName; extern char* ramFileName; extern char* stateFileName; @@ -47,10 +47,18 @@ extern char* mediumFont; extern char* largeFont; extern char* connFont; +#define MAX_LENGTH_FILENAME 2048 +extern char normalized_config_path[ MAX_LENGTH_FILENAME ]; +extern char normalized_rom_path[ MAX_LENGTH_FILENAME ]; +extern char normalized_ram_path[ MAX_LENGTH_FILENAME ]; +extern char normalized_state_path[ MAX_LENGTH_FILENAME ]; +extern char normalized_port1_path[ MAX_LENGTH_FILENAME ]; +extern char normalized_port2_path[ MAX_LENGTH_FILENAME ]; + /*************/ /* functions */ /*************/ -extern void get_home_directory( char* path ); +extern void get_absolute_config_dir( char* source, char* path ); extern int parse_args( int argc, char* argv[] ); #endif /* !_OPTIONS_H */ diff --git a/src/ui_sdl.c b/src/ui_sdl.c index 77016ca..cab7f2d 100644 --- a/src/ui_sdl.c +++ b/src/ui_sdl.c @@ -2415,7 +2415,7 @@ static void button_release_all( void ) { } static void SDLDrawSerialDevices() { - char text[ 1024 ]; + char text[ 1024 ] = ""; if ( verbose ) { fprintf( stderr, "wire_name: %s\n", wire_name ); From 7ba9008dd17b3f5a7fdbe25246200f637602d772 Mon Sep 17 00:00:00 2001 From: Gwenhael Le Moine Date: Wed, 20 Sep 2023 16:10:59 +0200 Subject: [PATCH 08/11] Usage section in README --- README.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/README.md b/README.md index aa6de6e..0667324 100644 --- a/README.md +++ b/README.md @@ -4,6 +4,12 @@ This is my fork of x48-0.6.4 where I deviate from the original code and do my own thing. +## Usage + +`./dist/x48ng --help` + +You can use the script `./dist/setup-x48ng-home.sh` or simply run `./dist/x48ng --rom=` + ## What have I done: 0. renamed it to x48ng to avoid confusion From 2a5d68dc80ddaab2ada571505b4ee86becc1b321 Mon Sep 17 00:00:00 2001 From: Gwenhael Le Moine Date: Wed, 20 Sep 2023 16:26:24 +0200 Subject: [PATCH 09/11] try to be resilient and helpful when dealing with files --- src/runtime_options.c | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/src/runtime_options.c b/src/runtime_options.c index cfcfc1a..ac865c6 100644 --- a/src/runtime_options.c +++ b/src/runtime_options.c @@ -1,3 +1,4 @@ +#include #include #include #include @@ -90,12 +91,26 @@ void get_absolute_config_dir( char* source, char* dest ) { } static inline void normalize_filenames( void ) { + struct stat st; + int normalized_config_path_exist = 0; + get_absolute_config_dir( configDir, normalized_config_path ); + if ( stat( normalized_config_path, &st ) == -1 ) + if ( errno == ENOENT ) + normalized_config_path_exist = 1; + if ( romFileName[ 0 ] == '/' ) strcpy( normalized_rom_path, "" ); - else + else { + if ( !normalized_config_path_exist ) { + fprintf( stderr, "ERROR: Cannot find rom `%s`\n", romFileName ); + fprintf( stderr, " You need a ROM to use %s\n", progname ); + + exit( 1 ); + } strcpy( normalized_rom_path, normalized_config_path ); + } strcat( normalized_rom_path, romFileName ); if ( ramFileName[ 0 ] == '/' ) From 187a69534a0cef21c1849782717af242ff8c4dca Mon Sep 17 00:00:00 2001 From: Gwenhael Le Moine Date: Wed, 20 Sep 2023 16:27:18 +0200 Subject: [PATCH 10/11] 0.26.0 --- Makefile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Makefile b/Makefile index 9319c42..4b11554 100644 --- a/Makefile +++ b/Makefile @@ -1,8 +1,8 @@ # Makefile to build x48ng without autotools VERSION_MAJOR = 0 -VERSION_MINOR = 25 -PATCHLEVEL = 1 +VERSION_MINOR = 26 +PATCHLEVEL = 0 MAKEFLAGS +=-j$(NUM_CORES) -l$(NUM_CORES) From 29a5ae530d0fa00cf2026d830ae26f6df523ac46 Mon Sep 17 00:00:00 2001 From: Gwenhael Le Moine Date: Wed, 20 Sep 2023 17:22:14 +0200 Subject: [PATCH 11/11] 0.26.1 C needs booleans --- Makefile | 2 +- src/runtime_options.c | 7 +++++-- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/Makefile b/Makefile index 4b11554..028b045 100644 --- a/Makefile +++ b/Makefile @@ -2,7 +2,7 @@ VERSION_MAJOR = 0 VERSION_MINOR = 26 -PATCHLEVEL = 0 +PATCHLEVEL = 1 MAKEFLAGS +=-j$(NUM_CORES) -l$(NUM_CORES) diff --git a/src/runtime_options.c b/src/runtime_options.c index ac865c6..962c747 100644 --- a/src/runtime_options.c +++ b/src/runtime_options.c @@ -92,13 +92,16 @@ void get_absolute_config_dir( char* source, char* dest ) { static inline void normalize_filenames( void ) { struct stat st; - int normalized_config_path_exist = 0; + int normalized_config_path_exist = 1; get_absolute_config_dir( configDir, normalized_config_path ); + if ( verbose ) + fprintf( stderr, "normalized_config_path: %s\n", + normalized_config_path ); if ( stat( normalized_config_path, &st ) == -1 ) if ( errno == ENOENT ) - normalized_config_path_exist = 1; + normalized_config_path_exist = 0; if ( romFileName[ 0 ] == '/' ) strcpy( normalized_rom_path, "" );