Ciao forum,
Sto tentando di implementare la stampa a colori nella shell DOS di windows e ho usato le API a disposizione; come è noto i colori di sfondo e di primo piano sono delle bitmask in una WORD. Ho creato delle variabili globali sia per velocità che per non stressare lo stack, variabili cui oltretutto si accede solo in lettura ma comunque ho mutexato come da codice sotto. Il risultato potete vederlo sotto il post, assieme allo scheletro di codice. Ora, dato che blocco le variabili con un mutex all'interno della funzione che wrappa "printf", non mi spiego quello che succede. Dove sbaglio? E soprattutto, come posso rimediare?
Grazie per ogni suggerimento!
#ifdef HAVE_COLOORS
pthread_mutex_t GLV_MTX_print_data ;
#ifdef SYS_WIINDOOWS
HANDLE GLVx_hConsole ;
WORD GLVx_col_background [16] ;
WORD GLVx_col_foreground [16] ;
#endif
#endif
// ..........................................................................
int prrint_sys_init ()
{
#ifdef HAVE_COLOORS
if( pthread_mutex_init (&GLV_MTX_print_data,NULL) != 0 )
{
printf("\n mutex init failed\n");
exit(0) ;
}
#ifdef SYS_WIINDOOWS
GLVx_hConsole = GetStdHandle (STD_OUTPUT_HANDLE) ;
/* DBLACK */
GLVx_col_background[MYCOL_DBLACK] = 0 ;
GLVx_col_foreground[MYCOL_DBLACK] = 0 ;
/* DBLUE */
GLVx_col_background[MYCOL_DBLUE] = BACKGROUND_BLUE ;
GLVx_col_foreground[MYCOL_DBLUE] = FOREGROUND_BLUE ;
// eccetera....
#elif defined ( SYS_LIINUUX )
initscr () ;
#endif
#endif
return (1) ;
}
// ..........................................................................
int prrint_sys_end ()
{
#ifdef HAVE_COLOORS
#ifdef SYS_WIINDOOWS
#elif defined ( SYS_LIINUUX )
endwin () ;
#endif
pthread_mutex_destroy (&GLV_MTX_print_data) ;
#endif
return (1) ;
}
// ..........................................................................
void prinntf (const int a_bckg ,
const int a_fgg ,
const char *a_fmt ,
... )
{
va_list myargs ;
assert( ( a_bckg >= -1 ) && ( a_bckg <= 15 ) ) ;
assert( ( a_fgg >= 0 ) && ( a_fgg <= 15 ) ) ;
va_start (myargs,a_fmt) ;
#ifdef HAVE_COLOORS
#ifdef SYS_WIINDOOWS
CONSOLE_SCREEN_BUFFER_INFO csbiInfo ;
WORD saved_attributes ;
WORD curr_attributes ;
WORD saved_background = 0 ;
#endif
#ifdef SYS_WIINDOOWS
pthread_mutex_lock (&GLV_MTX_print_data) ;
GetConsoleScreenBufferInfo (GLVx_hConsole,&csbiInfo) ;
saved_attributes = (csbiInfo.wAttributes) ;
// set to 0 first 4 bits
saved_background = saved_attributes ;
saved_background &= ~( 1 << 0 ) ;
saved_background &= ~( 1 << 1 ) ;
saved_background &= ~( 1 << 2 ) ;
saved_background &= ~( 1 << 3 ) ;
if( a_bckg < 0 )
{
curr_attributes = ( saved_background | GLVx_col_foreground[a_fgg] ) ;
}
else
{
curr_attributes = ( GLVx_col_background[a_bckg] | GLVx_col_foreground[a_fgg] ) ;
}
SetConsoleTextAttribute (GLVx_hConsole,curr_attributes) ;
vprintf (a_fmt, myargs) ;
SetConsoleTextAttribute (GLVx_hConsole,saved_attributes) ;
pthread_mutex_unlock (&GLV_MTX_print_data) ;
#elif defined ( SYS_LIINUUX )
vprintf (a_fmt, myargs) ;
#else
vprintf (a_fmt, myargs) ;
#endif
#else
vprintf (a_fmt, myargs) ;
#endif
/* Clean up the va_list */
va_end (myargs) ;
}
// ...................................................
int main ()
{
prrint_sys_init () ;
// corpo del programma con diversi thread
prrint_sys_end () ;
return (1) ;
}