Browse Source

extensions_manager: Introduce typed callbacks for extensions_manager

This commit introduces a typed virtual table for operations on
extensions_manager, aiming at replacing the legacy pf_control() callback
which is using va_list.

The operations can now be implemented directly by the modules, providing
type safety at every level.

When no operation is provided (i.e., extensions_manager_t.ops is NULL) by a
module implementation, the legacy pf_control will be used instead as a fallback.
pull/162/head
Vikram Kangotra 2 years ago
committed by Steve Lhomme
parent
commit
2e462c5062
  1. 34
      include/vlc_extensions.h
  2. 1
      src/Makefile.am
  3. 1
      src/libvlccore.sym
  4. 1
      src/meson.build
  5. 113
      src/misc/extensions.c

34
include/vlc_extensions.h

@ -55,6 +55,20 @@ typedef struct extension_t {
int i_icondata_size; /**< Size of that data */
} extension_t;
struct vlc_extensions_manager_operations {
int (*activate)(extensions_manager_t*, extension_t *);
int (*deactivate)(extensions_manager_t *, extension_t *);
bool (*is_activated)(extensions_manager_t *, extension_t *);
bool (*has_menu)(extensions_manager_t *, extension_t *);
int (*get_menu)(extensions_manager_t *, extension_t *, char ***, uint16_t **);
bool (*trigger_only)(extensions_manager_t *, extension_t *);
int (*trigger)(extensions_manager_t *, extension_t *);
int (*trigger_menu)(extensions_manager_t *, extension_t *, int);
int (*set_input)(extensions_manager_t *, extension_t *, input_item_t *);
int (*playing_changed)(extensions_manager_t *, extension_t *, int);
int (*meta_changed)(extensions_manager_t *, extension_t *);
};
/** Extensions manager object */
struct extensions_manager_t
{
@ -67,8 +81,19 @@ struct extensions_manager_t
DECL_ARRAY(extension_t*) extensions; /**< Array of extension descriptors */
vlc_mutex_t lock; /**< A lock for the extensions array */
/** Control, see extension_Control */
/** Control, see extension_Control
*
* Legacy way of implementing callbacks.
* \ref vlc_extensions_manager_operations should be preferred.
*/
int (*pf_control)(extensions_manager_t*, int, extension_t *, va_list);
/**
* Implementation of the extension manager operations.
*
* If NULL all operations will be redirected to \ref extensions_manager_t.pf_control
*/
const struct vlc_extensions_manager_operations *ops;
};
/* Control commands */
@ -88,6 +113,11 @@ enum
EXTENSION_META_CHANGED, /**< arg1: extension_t*, arg2 (input_item_t*) */
};
VLC_API int vlc_extension_VaControl( extensions_manager_t *p_mgr,
int i_control,
extension_t *ext,
va_list args );
/**
* Control function for extensions.
* Every GUI -> extension command will go through this function.
@ -98,7 +128,7 @@ static inline int extension_Control( extensions_manager_t *p_mgr,
{
va_list args;
va_start(args, ext);
int i_ret = p_mgr->pf_control(p_mgr, i_control, ext, args);
int i_ret = vlc_extension_VaControl(p_mgr, i_control, ext, args);
va_end( args );
return i_ret;
}

1
src/Makefile.am

@ -392,6 +392,7 @@ libvlccore_la_SOURCES = \
misc/fourcc.c \
misc/fourcc_list.h \
misc/es_format.c \
misc/extensions.c \
misc/picture.c \
misc/picture.h \
misc/picture_fifo.c \

1
src/libvlccore.sym

@ -113,6 +113,7 @@ es_format_Init
es_format_InitFromVideo
es_format_IsSimilar
es_format_LogDifferences
vlc_extension_VaControl
filter_AddProxyCallbacks
filter_DelProxyCallbacks
filter_Blend

1
src/meson.build

@ -243,6 +243,7 @@ libvlccore_sources_base = files(
'misc/fourcc.c',
'misc/fourcc_list.h',
'misc/es_format.c',
'misc/extensions.c',
'misc/picture.c',
'misc/picture.h',
'misc/picture_fifo.c',

113
src/misc/extensions.c

@ -0,0 +1,113 @@
/*****************************************************************************
* extensions.c
*****************************************************************************
* Copyright (C) 2024 VideoLabs
*
* Authors: Vikram Kangotra <vikramkangotra8055@gmail.com>
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published
* by the Free Software Foundation; either version 2.1 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
*****************************************************************************/
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include <assert.h>
#include <vlc_common.h>
#include <vlc_extensions.h>
int vlc_extension_VaControl( extensions_manager_t *p_mgr,
int i_control,
extension_t *ext,
va_list args )
{
if (p_mgr->ops == NULL)
return p_mgr->pf_control(p_mgr, i_control, ext, args);
switch (i_control) {
case EXTENSION_ACTIVATE:
if (p_mgr->ops->activate != NULL)
return p_mgr->ops->activate(p_mgr, ext);
return VLC_EGENERIC;
case EXTENSION_DEACTIVATE:
if (p_mgr->ops->deactivate != NULL)
return p_mgr->ops->deactivate(p_mgr, ext);
return VLC_EGENERIC;
case EXTENSION_IS_ACTIVATED:
{
bool *is_activated = va_arg(args, bool *);
if (p_mgr->ops->is_activated != NULL)
*is_activated = p_mgr->ops->is_activated(p_mgr, ext);
else
*is_activated = false;
return VLC_SUCCESS;
}
case EXTENSION_HAS_MENU:
{
bool *has_menu = va_arg(args, bool *);
if (p_mgr->ops->has_menu != NULL)
*has_menu = p_mgr->ops->has_menu(p_mgr, ext);
else
*has_menu = false;
return VLC_SUCCESS;
}
case EXTENSION_GET_MENU:
if (p_mgr->ops->get_menu != NULL) {
char ***pppsz_titles = va_arg(args, char ***);
uint16_t **ppi_ids = va_arg(args, uint16_t **);
return p_mgr->ops->get_menu(p_mgr, ext, pppsz_titles, ppi_ids);
}
return VLC_EGENERIC;
case EXTENSION_TRIGGER_ONLY:
{
bool *p_trigger_only = va_arg(args, bool *);
if (p_mgr->ops->trigger_only != NULL)
*p_trigger_only = p_mgr->ops->trigger_only(p_mgr, ext);
else
*p_trigger_only = false;
return VLC_SUCCESS;
}
case EXTENSION_TRIGGER:
if (p_mgr->ops->trigger != NULL)
return p_mgr->ops->trigger(p_mgr, ext);
return VLC_EGENERIC;
case EXTENSION_TRIGGER_MENU:
if (p_mgr->ops->trigger_menu != NULL) {
int i = va_arg(args, int);
return p_mgr->ops->trigger_menu(p_mgr, ext, i);
}
return VLC_EGENERIC;
case EXTENSION_SET_INPUT:
if (p_mgr->ops->set_input != NULL) {
input_item_t *p_item = va_arg(args, input_item_t *);
return p_mgr->ops->set_input(p_mgr, ext, p_item);
}
return VLC_EGENERIC;
case EXTENSION_PLAYING_CHANGED:
if (p_mgr->ops->playing_changed != NULL) {
int i = va_arg(args, int);
return p_mgr->ops->playing_changed(p_mgr, ext, i);
}
return VLC_EGENERIC;
case EXTENSION_META_CHANGED:
if (p_mgr->ops->meta_changed != NULL)
return p_mgr->ops->meta_changed(p_mgr, ext);
return VLC_EGENERIC;
default:
vlc_assert_unreachable();
}
}
Loading…
Cancel
Save