X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=src%2Fmisc%2Fmessages.c;h=063ae608af898377900788fa088232727f9978fd;hb=532b014ad9c53a3ef32a74373fdb895726bde516;hp=45af2e510648b1e392978f4eda4bfe57d8a46126;hpb=4e29ccba6220630f8cc34b9aa64c787b84613f80;p=vlc diff --git a/src/misc/messages.c b/src/misc/messages.c index 45af2e5106..063ae608af 100644 --- a/src/misc/messages.c +++ b/src/misc/messages.c @@ -35,7 +35,11 @@ #include #include /* va_list for BSD */ -#include +#ifdef __APPLE__ +# include +#elif defined(HAVE_LOCALE_H) +# include +#endif #include /* errno */ #ifdef WIN32 @@ -78,52 +82,58 @@ static uintptr_t banks = 0; # define vlc_va_copy(dest,src) (dest)=(src) #endif -#define QUEUE priv->msg_bank static inline msg_bank_t *libvlc_bank (libvlc_int_t *inst) { - return &(libvlc_priv (inst))->msg_bank; + return (libvlc_priv (inst))->msg_bank; } /***************************************************************************** * Local prototypes *****************************************************************************/ -static void QueueMsg ( vlc_object_t *, int, const char *, - const char *, va_list ); static void PrintMsg ( vlc_object_t *, msg_item_t * ); static vlc_mutex_t msg_stack_lock = VLC_STATIC_MUTEX; +/** + * Store all data required by messages interfaces. + */ +struct msg_bank_t +{ + /** Message queue lock */ + vlc_rwlock_t lock; + + /* Subscribers */ + int i_sub; + msg_subscription_t **pp_sub; + + locale_t locale; /**< C locale for error messages */ + vlc_dictionary_t enabled_objects; ///< Enabled objects + bool all_objects_enabled; ///< Should we print all objects? +}; + /** * Initialize messages queues * This function initializes all message queues */ -void msg_Create (libvlc_int_t *p_libvlc) +msg_bank_t *msg_Create (void) { - libvlc_priv_t *priv = libvlc_priv (p_libvlc); - msg_bank_t *bank = libvlc_bank (p_libvlc); + msg_bank_t *bank = malloc (sizeof (*bank)); vlc_rwlock_init (&bank->lock); - vlc_dictionary_init( &priv->msg_enabled_objects, 0 ); - priv->msg_all_objects_enabled = true; + vlc_dictionary_init (&bank->enabled_objects, 0); + bank->all_objects_enabled = true; - QUEUE.i_sub = 0; - QUEUE.pp_sub = NULL; + bank->i_sub = 0; + bank->pp_sub = NULL; /* C locale to get error messages in English in the logs */ bank->locale = newlocale (LC_MESSAGES_MASK, "C", (locale_t)0); -#ifdef UNDER_CE - QUEUE.logfile = - CreateFile( L"vlc-log.txt", GENERIC_WRITE, - FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, - CREATE_ALWAYS, 0, NULL ); - SetFilePointer( QUEUE.logfile, 0, NULL, FILE_END ); -#endif - vlc_mutex_lock( &msg_stack_lock ); if( banks++ == 0 ) vlc_threadvar_create( &msg_context, cleanup_msg_context ); vlc_mutex_unlock( &msg_stack_lock ); + return bank; } /** @@ -132,26 +142,33 @@ void msg_Create (libvlc_int_t *p_libvlc) static void const * kObjectPrintingEnabled = &kObjectPrintingEnabled; static void const * kObjectPrintingDisabled = &kObjectPrintingDisabled; -void __msg_EnableObjectPrinting (vlc_object_t *p_this, const char * psz_object) + +#undef msg_EnableObjectPrinting +void msg_EnableObjectPrinting (vlc_object_t *obj, const char * psz_object) { - libvlc_priv_t *priv = libvlc_priv (p_this->p_libvlc); - vlc_rwlock_wrlock( &QUEUE.lock ); + msg_bank_t *bank = libvlc_bank (obj->p_libvlc); + + vlc_rwlock_wrlock (&bank->lock); if( !strcmp(psz_object, "all") ) - priv->msg_all_objects_enabled = true; + bank->all_objects_enabled = true; else - vlc_dictionary_insert( &priv->msg_enabled_objects, psz_object, (void *)kObjectPrintingEnabled ); - vlc_rwlock_unlock( &QUEUE.lock ); + vlc_dictionary_insert (&bank->enabled_objects, psz_object, + (void *)kObjectPrintingEnabled); + vlc_rwlock_unlock (&bank->lock); } -void __msg_DisableObjectPrinting (vlc_object_t *p_this, const char * psz_object) +#undef msg_DisableObjectPrinting +void msg_DisableObjectPrinting (vlc_object_t *obj, const char * psz_object) { - libvlc_priv_t *priv = libvlc_priv (p_this->p_libvlc); - vlc_rwlock_wrlock( &QUEUE.lock ); + msg_bank_t *bank = libvlc_bank (obj->p_libvlc); + + vlc_rwlock_wrlock (&bank->lock); if( !strcmp(psz_object, "all") ) - priv->msg_all_objects_enabled = false; + bank->all_objects_enabled = false; else - vlc_dictionary_insert( &priv->msg_enabled_objects, psz_object, (void *)kObjectPrintingDisabled ); - vlc_rwlock_unlock( &QUEUE.lock ); + vlc_dictionary_insert (&bank->enabled_objects, psz_object, + (void *)kObjectPrintingDisabled); + vlc_rwlock_unlock (&bank->lock); } /** @@ -161,13 +178,10 @@ void __msg_DisableObjectPrinting (vlc_object_t *p_this, const char * psz_object) * then frees all the allocated resources * No other messages interface functions should be called after this one. */ -void msg_Destroy (libvlc_int_t *p_libvlc) +void msg_Destroy (msg_bank_t *bank) { - libvlc_priv_t *priv = libvlc_priv (p_libvlc); - msg_bank_t *bank = libvlc_bank (p_libvlc); - - if( QUEUE.i_sub ) - msg_Err( p_libvlc, "stale interface subscribers (VLC might crash)" ); + if (unlikely(bank->i_sub != 0)) + fputs ("stale interface subscribers (LibVLC might crash)\n", stderr); vlc_mutex_lock( &msg_stack_lock ); assert(banks > 0); @@ -175,15 +189,13 @@ void msg_Destroy (libvlc_int_t *p_libvlc) vlc_threadvar_delete( &msg_context ); vlc_mutex_unlock( &msg_stack_lock ); -#ifdef UNDER_CE - CloseHandle( QUEUE.logfile ); -#endif if (bank->locale != (locale_t)0) freelocale (bank->locale); - vlc_dictionary_clear( &priv->msg_enabled_objects, NULL, NULL ); + vlc_dictionary_clear (&bank->enabled_objects, NULL, NULL); vlc_rwlock_destroy (&bank->lock); + free (bank); } struct msg_subscription_t @@ -191,6 +203,7 @@ struct msg_subscription_t libvlc_int_t *instance; msg_callback_t func; msg_cb_data_t *opaque; + int verbosity; }; /** @@ -213,6 +226,7 @@ msg_subscription_t *msg_Subscribe (libvlc_int_t *instance, msg_callback_t cb, sub->instance = instance; sub->func = cb; sub->opaque = opaque; + sub->verbosity = 2; /* by default, give all the messages */ msg_bank_t *bank = libvlc_bank (instance); vlc_rwlock_wrlock (&bank->lock); @@ -236,27 +250,33 @@ void msg_Unsubscribe (msg_subscription_t *sub) free (sub); } +void msg_SubscriptionSetVerbosity( msg_subscription_t *sub, const int i_verbosity ) +{ + if( i_verbosity < 0 || i_verbosity > 2 ) return; + + msg_bank_t *bank = libvlc_bank ( sub->instance ); + + vlc_rwlock_wrlock (&bank->lock); + + sub->verbosity = i_verbosity; + + vlc_rwlock_unlock (&bank->lock); +} /***************************************************************************** - * __msg_*: print a message + * msg_*: print a message ***************************************************************************** * These functions queue a message for later printing. *****************************************************************************/ -void __msg_Generic( vlc_object_t *p_this, int i_type, const char *psz_module, +void msg_Generic( vlc_object_t *p_this, int i_type, const char *psz_module, const char *psz_format, ... ) { va_list args; va_start( args, psz_format ); - QueueMsg( p_this, i_type, psz_module, psz_format, args ); + msg_GenericVa (p_this, i_type, psz_module, psz_format, args); va_end( args ); } -void __msg_GenericVa( vlc_object_t *p_this, int i_type, const char *psz_module, - const char *psz_format, va_list args ) -{ - QueueMsg( p_this, i_type, psz_module, psz_format, args ); -} - /** * Destroys a message. */ @@ -270,6 +290,7 @@ static void msg_Free (gc_object_t *gc) free (msg); } +#undef msg_GenericVa /** * Add a message to a queue * @@ -278,22 +299,23 @@ static void msg_Free (gc_object_t *gc) * is full). If the message can't be converted to string in memory, it issues * a warning. */ -static void QueueMsg( vlc_object_t *p_this, int i_type, const char *psz_module, - const char *psz_format, va_list _args ) +void msg_GenericVa (vlc_object_t *p_this, int i_type, + const char *psz_module, + const char *psz_format, va_list _args) { - assert (p_this); - libvlc_priv_t *priv = libvlc_priv (p_this->p_libvlc); - int i_header_size; /* Size of the additionnal header */ + size_t i_header_size; /* Size of the additionnal header */ vlc_object_t *p_obj; char * psz_str = NULL; /* formatted message string */ char * psz_header = NULL; va_list args; + assert (p_this); + if( p_this->i_flags & OBJECT_FLAGS_QUIET || (p_this->i_flags & OBJECT_FLAGS_NODBG && i_type == VLC_MSG_DBG) ) return; - msg_bank_t *bank = &QUEUE; + msg_bank_t *bank = libvlc_bank (p_this->p_libvlc); locale_t locale = uselocale (bank->locale); #ifndef __GLIBC__ @@ -435,6 +457,33 @@ static void QueueMsg( vlc_object_t *p_this, int i_type, const char *psz_module, for (int i = 0; i < bank->i_sub; i++) { msg_subscription_t *sub = bank->pp_sub[i]; + libvlc_priv_t *priv = libvlc_priv( sub->instance ); + msg_bank_t *bank = priv->msg_bank; + void *val = vlc_dictionary_value_for_key( &bank->enabled_objects, + p_item->psz_module ); + if( val == kObjectPrintingDisabled ) continue; + if( val != kObjectPrintingEnabled ) /*if not allowed */ + { + val = vlc_dictionary_value_for_key( &bank->enabled_objects, + p_item->psz_object_type ); + if( val == kObjectPrintingDisabled ) continue; + if( val == kObjectPrintingEnabled ); /* Allowed */ + else if( !bank->all_objects_enabled ) continue; + } + switch( p_item->i_type ) + { + case VLC_MSG_INFO: + case VLC_MSG_ERR: + if( sub->verbosity < 0 ) continue; + break; + case VLC_MSG_WARN: + if( sub->verbosity < 1 ) continue; + break; + case VLC_MSG_DBG: + if( sub->verbosity < 2 ) continue; + break; + } + sub->func (sub->opaque, p_item, 0); } vlc_rwlock_unlock (&bank->lock); @@ -448,20 +497,18 @@ static void QueueMsg( vlc_object_t *p_this, int i_type, const char *psz_module, *****************************************************************************/ static void PrintMsg ( vlc_object_t * p_this, msg_item_t * p_item ) { -# define COL(x) "\033[" #x ";1m" -# define RED COL(31) -# define GREEN COL(32) -# define YELLOW COL(33) -# define WHITE COL(0) +# define COL(x,y) "\033[" #x ";" #y "m" +# define RED COL(31,1) +# define GREEN COL(32,1) +# define YELLOW COL(0,33) +# define WHITE COL(0,1) # define GRAY "\033[0m" -#ifdef UNDER_CE - int i_dummy; -#endif static const char ppsz_type[4][9] = { "", " error", " warning", " debug" }; static const char ppsz_color[4][8] = { WHITE, RED, YELLOW, GRAY }; const char *psz_object; libvlc_priv_t *priv = libvlc_priv (p_this->p_libvlc); + msg_bank_t *bank = priv->msg_bank; int i_type = p_item->i_type; switch( i_type ) @@ -481,37 +528,24 @@ static void PrintMsg ( vlc_object_t * p_this, msg_item_t * p_item ) } psz_object = p_item->psz_object_type; - void * val = vlc_dictionary_value_for_key( &priv->msg_enabled_objects, - p_item->psz_module ); + void * val = vlc_dictionary_value_for_key (&bank->enabled_objects, + p_item->psz_module); if( val == kObjectPrintingDisabled ) return; if( val == kObjectPrintingEnabled ) /* Allowed */; else { - val = vlc_dictionary_value_for_key( &priv->msg_enabled_objects, - psz_object ); + val = vlc_dictionary_value_for_key (&bank->enabled_objects, + psz_object); if( val == kObjectPrintingDisabled ) return; if( val == kObjectPrintingEnabled ) /* Allowed */; - else if( !priv->msg_all_objects_enabled ) + else if( !bank->all_objects_enabled ) return; } -#ifdef UNDER_CE -# define CE_WRITE(str) WriteFile( QUEUE.logfile, \ - str, strlen(str), &i_dummy, NULL ); - CE_WRITE( p_item->psz_module ); - CE_WRITE( " " ); - CE_WRITE( psz_object ); - CE_WRITE( ppsz_type[i_type] ); - CE_WRITE( ": " ); - CE_WRITE( p_item->psz_msg ); - CE_WRITE( "\r\n" ); - FlushFileBuffers( QUEUE.logfile ); - -#else int canc = vlc_savecancel (); /* Send the message to stderr */ utf8_fprintf( stderr, "[%s%p%s] %s%s%s %s%s: %s%s%s\n", @@ -526,11 +560,10 @@ static void PrintMsg ( vlc_object_t * p_this, msg_item_t * p_item ) p_item->psz_msg, priv->b_color ? GRAY : "" ); -# if defined(WIN32) +#ifdef WIN32 fflush( stderr ); -# endif - vlc_restorecancel (canc); #endif + vlc_restorecancel (canc); } static msg_context_t* GetContext(void) @@ -547,14 +580,6 @@ static msg_context_t* GetContext(void) return p_ctx; } -void msg_StackDestroy (void *data) -{ - msg_context_t *p_ctx = data; - - free (p_ctx->psz_message); - free (p_ctx); -} - void msg_StackSet( int i_code, const char *psz_message, ... ) { va_list ap;