/*****************************************************************************
* directx.c: Windows DirectDraw video output
*****************************************************************************
- * Copyright (C) 2001-2009 the VideoLAN team
+ * Copyright (C) 2001-2009 VLC authors and VideoLAN
* $Id$
*
* Authors: Gildas Bazin <gbazin@videolan.org>
*
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
+ * 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 General Public License for more details.
+ * 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 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.
+ * 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.
*****************************************************************************/
/*****************************************************************************
* display video in window mode.
*
*****************************************************************************/
+
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
+
#include <assert.h>
#include <vlc_common.h>
#include <vlc_plugin.h>
#include <vlc_vout_display.h>
-#include <vlc_playlist.h> /* needed for wallpaper */
+#include <vlc_charset.h> /* FromT */
+#include <windows.h>
#include <ddraw.h>
#include <commctrl.h> /* ListView_(Get|Set)* */
-#ifndef UNDER_CE
-# include <multimon.h>
-#endif
-#undef GetSystemMetrics
-
-#ifndef MONITOR_DEFAULTTONEAREST
-# define MONITOR_DEFAULTTONEAREST 2
-#endif
-
#include "common.h"
+/* Unicode function "DirectDrawEnumerateExW" has been desactivated
+ since in some cases this function fails and the callbacks are not
+ called. If the Unicode mode is restored, one should modify the
+ prototype of the callbacks and call the FromT conversion function.
+*/
+#define DIRECTDRAWENUMERATEEX_NAME "DirectDrawEnumerateExA"
+
/*****************************************************************************
* Module descriptor
*****************************************************************************/
#define SYSMEM_TEXT N_("Use video buffers in system memory")
#define SYSMEM_LONGTEXT N_(\
"Create video buffers in system memory instead of video memory. This " \
- "isn't recommended as usually using video memory allows to benefit from " \
+ "isn't recommended as usually using video memory allows benefiting from " \
"more hardware acceleration (like rescaling or YUV->RGB conversions). " \
"This option doesn't have any effect when using overlays.")
#define DX_HELP N_("Recommended video output for Windows XP. " \
"Incompatible with Vista's Aero interface" )
-static const char * const device[] = { "" };
-static const char * const device_text[] = { N_("Default") };
-
static int Open (vlc_object_t *);
static void Close(vlc_object_t *);
-static int FindDevicesCallback(vlc_object_t *, char const *,
- vlc_value_t, vlc_value_t, void *);
+static int FindDevicesCallback(vlc_object_t *, const char *,
+ char ***, char ***);
vlc_module_begin()
set_shortname("DirectX")
set_description(N_("DirectX (DirectDraw) video output"))
set_help(DX_HELP)
set_category(CAT_VIDEO)
set_subcategory(SUBCAT_VIDEO_VOUT)
- add_bool("directx-hw-yuv", true, NULL, HW_YUV_TEXT, HW_YUV_LONGTEXT,
+ add_bool("directx-hw-yuv", true, HW_YUV_TEXT, HW_YUV_LONGTEXT,
true)
- add_bool("directx-use-sysmem", false, NULL, SYSMEM_TEXT, SYSMEM_LONGTEXT,
+ add_bool("directx-use-sysmem", false, SYSMEM_TEXT, SYSMEM_LONGTEXT,
true)
- add_bool("directx-3buffering", true, NULL, TRIPLEBUF_TEXT,
+ add_bool("directx-3buffering", true, TRIPLEBUF_TEXT,
TRIPLEBUF_LONGTEXT, true)
- add_string("directx-device", "", NULL, DEVICE_TEXT, DEVICE_LONGTEXT, true)
- change_string_list(device, device_text, FindDevicesCallback)
- change_action_add(FindDevicesCallback, N_("Refresh list"))
+ add_string("directx-device", "", DEVICE_TEXT, DEVICE_LONGTEXT, true)
+ change_string_cb(FindDevicesCallback)
- set_capability("vout display", 100)
+ set_capability("vout display", 230)
add_shortcut("directx")
set_callbacks(Open, Close)
-
- /* FIXME: Hack to avoid unregistering our window class */
- cannot_unload_broken_library()
vlc_module_end()
-#if 0 /* FIXME */
- /* check if we registered a window class because we need to
- * unregister it */
- WNDCLASS wndclass;
- if (GetClassInfo(GetModuleHandle(NULL), "VLC DirectX", &wndclass))
- UnregisterClass("VLC DirectX", GetModuleHandle(NULL));
-#endif
-
/*****************************************************************************
* Local prototypes.
*****************************************************************************/
struct picture_sys_t {
LPDIRECTDRAWSURFACE2 surface;
LPDIRECTDRAWSURFACE2 front_surface;
+ picture_t *fallback;
};
/*****************************************************************************
DEFINE_GUID(IID_IDirectDrawSurface2, 0x57805885,0x6eec,0x11cf,0x94,0x41,0xa8,0x23,0x03,0xc1,0x0e,0x27);
static picture_pool_t *Pool (vout_display_t *, unsigned);
-static void Display(vout_display_t *, picture_t *);
+static void Display(vout_display_t *, picture_t *, subpicture_t *);
static int Control(vout_display_t *, int, va_list);
static void Manage (vout_display_t *);
return VLC_EGENERIC;
}
- /* */
- HMODULE huser32 = GetModuleHandle(_T("USER32"));
- if (huser32) {
- sys->MonitorFromWindow = (void*)GetProcAddress(huser32, _T("MonitorFromWindow"));
- sys->GetMonitorInfo = (void*)GetProcAddress(huser32, _T("GetMonitorInfoW"));
- } else {
- sys->MonitorFromWindow = NULL;
- sys->GetMonitorInfo = NULL;
- }
-
/* */
sys->use_wallpaper = var_CreateGetBool(vd, "video-wallpaper");
/* FIXME */
sys->use_overlay = false;//var_CreateGetBool(vd, "overlay"); /* FIXME */
+ sys->restore_overlay = false;
var_Create(vd, "directx-device", VLC_VAR_STRING | VLC_VAR_DOINHERIT);
/* Initialisation */
vout_display_info_t info = vd->info;
info.is_slow = true;
info.has_double_click = true;
- info.has_hide_mouse = true;
+ info.has_hide_mouse = false;
info.has_pictures_invalid = true;
+ info.has_event_thread = true;
/* Interaction TODO support starting with wallpaper mode */
vlc_mutex_init(&sys->lock);
var_AddCallback(vd, "video-wallpaper", WallpaperCallback, NULL);
/* Setup vout_display now that everything is fine */
- vd->fmt = fmt;
+ video_format_Clean(&vd->fmt);
+ video_format_Copy(&vd->fmt, &fmt);
vd->info = info;
vd->pool = Pool;
return VLC_SUCCESS;
error:
- Close(VLC_OBJECT(vd));
+ DirectXClose(vd);
+ CommonClean(vd);
+ if (sys->hddraw_dll)
+ FreeLibrary(sys->hddraw_dll);
+ free(sys);
return VLC_EGENERIC;
}
VLC_UNUSED(count);
return vd->sys->pool;
}
-static void Display(vout_display_t *vd, picture_t *picture)
+static void Display(vout_display_t *vd, picture_t *picture, subpicture_t *subpicture)
{
vout_display_sys_t *sys = vd->sys;
DirectXUpdateOverlay(vd, NULL);
}
}
+ if (sys->restore_overlay)
+ DirectXUpdateOverlay(vd, NULL);
/* */
DirectXUnlock(picture);
CommonDisplay(vd);
picture_Release(picture);
+ VLC_UNUSED(subpicture);
}
static int Control(vout_display_t *vd, int query, va_list args)
{
DirectXUpdateOverlay(vd, NULL);
/* Check if we are still on the same monitor */
- if (sys->MonitorFromWindow &&
- sys->hmonitor != sys->MonitorFromWindow(sys->hwnd, MONITOR_DEFAULTTONEAREST)) {
+ HMONITOR hmon = MonitorFromWindow(sys->hwnd, MONITOR_DEFAULTTONEAREST);
+ if (sys->hmonitor != hmon) {
vout_display_SendEventPicturesInvalid(vd);
}
/* */
if (ch_wallpaper)
WallpaperChange(vd, wallpaper_requested);
+
+ /* */
+ if (sys->restore_overlay)
+ DirectXUpdateOverlay(vd, NULL);
}
/* */
}
/* */
-static BOOL WINAPI DirectXOpenDDrawCallback(GUID *guid, LPTSTR desc,
- LPTSTR drivername, VOID *context,
+static BOOL WINAPI DirectXOpenDDrawCallback(GUID *guid, LPSTR desc,
+ LPSTR drivername, VOID *context,
HMONITOR hmon)
{
vout_display_t *vd = context;
if (!hmon)
return TRUE;
- msg_Dbg(vd, "DirectXEnumCallback: %s, %s", desc, drivername);
+ char *psz_drivername = drivername;
+ char *psz_desc = desc;
+
+ msg_Dbg(vd, "DirectXEnumCallback: %s, %s", psz_desc, psz_drivername);
char *device = var_GetString(vd, "directx-device");
/* Check for forced device */
- if (device && *device && !strcmp(drivername, device)) {
+ if (device && *device && !strcmp(psz_drivername, device)) {
MONITORINFO monitor_info;
monitor_info.cbSize = sizeof(MONITORINFO);
- if (sys->GetMonitorInfo(hmon, &monitor_info)) {
+ if (GetMonitorInfoA(hmon, &monitor_info)) {
RECT rect;
/* Move window to the right screen */
free(device);
if (hmon == sys->hmonitor) {
- msg_Dbg(vd, "selecting %s, %s", desc, drivername);
+ msg_Dbg(vd, "selecting %s, %s", psz_desc, psz_drivername);
free(sys->display_driver);
sys->display_driver = malloc(sizeof(*guid));
/* */
HRESULT (WINAPI *OurDirectDrawCreate)(GUID *,LPDIRECTDRAW *,IUnknown *);
OurDirectDrawCreate =
- (void *)GetProcAddress(sys->hddraw_dll, _T("DirectDrawCreate"));
+ (void *)GetProcAddress(sys->hddraw_dll, "DirectDrawCreate");
if (!OurDirectDrawCreate) {
msg_Err(vd, "DirectXInitDDraw failed GetProcAddress");
return VLC_EGENERIC;
}
/* */
- if (sys->MonitorFromWindow) {
- HRESULT (WINAPI *OurDirectDrawEnumerateEx)(LPDDENUMCALLBACKEXA, LPVOID, DWORD);
- OurDirectDrawEnumerateEx =
- (void *)GetProcAddress(sys->hddraw_dll, _T("DirectDrawEnumerateExW"));
-
- if (OurDirectDrawEnumerateEx) {
- char *device = var_GetString(vd, "directx-device");
- if (device) {
- msg_Dbg(vd, "directx-device: %s", device);
- free(device);
- }
+ HRESULT (WINAPI *OurDirectDrawEnumerateEx)(LPDDENUMCALLBACKEXA, LPVOID, DWORD);
+ OurDirectDrawEnumerateEx =
+ (void *)GetProcAddress(sys->hddraw_dll, DIRECTDRAWENUMERATEEX_NAME);
+
+ if (OurDirectDrawEnumerateEx) {
+ char *device = var_GetString(vd, "directx-device");
+ if (device) {
+ msg_Dbg(vd, "directx-device: %s", device);
+ free(device);
+ }
- sys->hmonitor = sys->MonitorFromWindow(sys->hwnd, MONITOR_DEFAULTTONEAREST);
+ sys->hmonitor = MonitorFromWindow(sys->hwnd, MONITOR_DEFAULTTONEAREST);
- /* Enumerate displays */
- OurDirectDrawEnumerateEx(DirectXOpenDDrawCallback,
- vd, DDENUM_ATTACHEDSECONDARYDEVICES);
- }
+ /* Enumerate displays */
+ OurDirectDrawEnumerateEx(DirectXOpenDDrawCallback,
+ vd, DDENUM_ATTACHEDSECONDARYDEVICES);
}
/* Initialize DirectDraw now */
}
/* Get the IDirectDraw2 interface */
+ void *ptr;
hr = IDirectDraw_QueryInterface(ddobject, &IID_IDirectDraw2,
- &sys->ddobject);
+ &ptr);
/* Release the unused interface */
IDirectDraw_Release(ddobject);
sys->ddobject = NULL;
return VLC_EGENERIC;
}
+ sys->ddobject = ptr;
/* Set DirectDraw Cooperative level, ie what control we want over Windows
* display */
}
/* Get the size of the current display device */
- if (sys->hmonitor && sys->GetMonitorInfo) {
+ if (sys->hmonitor) {
MONITORINFO monitor_info;
monitor_info.cbSize = sizeof(MONITORINFO);
- sys->GetMonitorInfo(vd->sys->hmonitor, &monitor_info);
+ GetMonitorInfoA(vd->sys->hmonitor, &monitor_info);
sys->rect_display = monitor_info.rcMonitor;
} else {
sys->rect_display.left = 0;
return VLC_EGENERIC;
}
+ void *ptr;
hr = IDirectDrawSurface_QueryInterface(display, &IID_IDirectDrawSurface2,
- &sys->display);
+ &ptr);
/* Release the old interface */
IDirectDrawSurface_Release(display);
sys->display = NULL;
return VLC_EGENERIC;
}
+ sys->display = ptr;
/* The clipper will be used only in non-overlay mode */
DirectXCreateClipper(vd);
ddsd.dwSize = sizeof(ddsd);
ddsd.ddpfPixelFormat.dwSize = sizeof(ddsd.ddpfPixelFormat);
ddsd.dwFlags = DDSD_HEIGHT | DDSD_WIDTH;
- ddsd.dwWidth = fmt->i_width;
- ddsd.dwHeight = fmt->i_height;
+ ddsd.dwWidth = fmt->i_visible_width;
+ ddsd.dwHeight = fmt->i_visible_height;
if (fourcc) {
ddsd.dwFlags |= DDSD_PIXELFORMAT;
ddsd.ddpfPixelFormat.dwFlags = DDPF_FOURCC;
static void DirectXUnlockSurface(LPDIRECTDRAWSURFACE2 front_surface,
LPDIRECTDRAWSURFACE2 surface)
{
+ VLC_UNUSED(front_surface);
IDirectDrawSurface2_Unlock(surface, NULL);
}
static int DirectXCheckLockingSurface(LPDIRECTDRAWSURFACE2 front_surface,
}
/* */
- picture_resource_t *rsc = &sys->resource;
- rsc->p_sys->front_surface = front_surface;
- rsc->p_sys->surface = surface;
+ picture_sys_t *picsys = sys->picsys;
+ picsys->front_surface = front_surface;
+ picsys->surface = surface;
+ picsys->fallback = NULL;
return VLC_SUCCESS;
}
static int DirectXCreatePictureResourceYuv(vout_display_t *vd,
}
/* */
- picture_resource_t *rsc = &sys->resource;
- rsc->p_sys->front_surface = surface;
- rsc->p_sys->surface = surface;
+ picture_sys_t *picsys = sys->picsys;
+ picsys->front_surface = surface;
+ picsys->surface = surface;
+ picsys->fallback = NULL;
return VLC_SUCCESS;
}
static int DirectXCreatePictureResourceRgb(vout_display_t *vd,
}
/* */
- picture_resource_t *rsc = &sys->resource;
- rsc->p_sys->front_surface = surface;
- rsc->p_sys->surface = surface;
+ picture_sys_t *picsys = sys->picsys;
+ picsys->front_surface = surface;
+ picsys->surface = surface;
+ picsys->fallback = NULL;
return VLC_SUCCESS;
}
vout_display_sys_t *sys = vd->sys;
/* */
- picture_resource_t *rsc = &sys->resource;
- rsc->p_sys = calloc(1, sizeof(*rsc->p_sys));
- if (!rsc->p_sys)
+ picture_sys_t *picsys = calloc(1, sizeof(*picsys));
+ if (unlikely(picsys == NULL))
return VLC_ENOMEM;
+ sys->picsys = picsys;
/* */
bool allow_hw_yuv = sys->can_blit_fourcc &&
{
vout_display_sys_t *sys = vd->sys;
- DirectXDestroySurface(sys->resource.p_sys->front_surface);
+ if (sys->picsys->front_surface != sys->picsys->surface)
+ DirectXDestroySurface(sys->picsys->surface);
+ DirectXDestroySurface(sys->picsys->front_surface);
+ if (sys->picsys->fallback)
+ picture_Release(sys->picsys->fallback);
}
static int DirectXLock(picture_t *picture)
DDSURFACEDESC ddsd;
if (DirectXLockSurface(picture->p_sys->front_surface,
picture->p_sys->surface, &ddsd))
- return VLC_EGENERIC;
-
- /* fill in buffer info in first plane */
- picture->p->p_pixels = ddsd.lpSurface;
- picture->p->i_pitch = ddsd.lPitch;
- picture->p->i_lines = picture->format.i_height;
+ return CommonUpdatePicture(picture, &picture->p_sys->fallback, NULL, 0);
- /* Fill chroma planes for planar YUV */
- if (picture->format.i_chroma == VLC_CODEC_I420 ||
- picture->format.i_chroma == VLC_CODEC_J420 ||
- picture->format.i_chroma == VLC_CODEC_YV12) {
-
- for (int n = 1; n < picture->i_planes; n++) {
- const plane_t *o = &picture->p[n-1];
- plane_t *p = &picture->p[n];
-
- p->p_pixels = o->p_pixels + o->i_lines * o->i_pitch;
- p->i_pitch = ddsd.lPitch / 2;
- p->i_lines = picture->format.i_height / 2;
- }
- /* The dx buffer is always allocated as YV12 */
- if (vlc_fourcc_AreUVPlanesSwapped(picture->format.i_chroma, VLC_CODEC_YV12)) {
- uint8_t *p_tmp = picture->p[1].p_pixels;
- picture->p[1].p_pixels = picture->p[2].p_pixels;
- picture->p[2].p_pixels = p_tmp;
- }
- }
+ CommonUpdatePicture(picture, NULL, ddsd.lpSurface, ddsd.lPitch);
return VLC_SUCCESS;
}
static void DirectXUnlock(picture_t *picture)
return VLC_EGENERIC;
/* Create the associated picture */
- picture_resource_t *rsc = &sys->resource;
- for (int i = 0; i < PICTURE_PLANE_MAX; i++) {
- rsc->p[i].p_pixels = NULL;
- rsc->p[i].i_pitch = 0;
- rsc->p[i].i_lines = 0;
- }
- picture_t *picture = picture_NewFromResource(fmt, rsc);
+ picture_resource_t resource = { .p_sys = sys->picsys };
+ picture_t *picture = picture_NewFromResource(fmt, &resource);
if (!picture) {
DirectXDestroyPictureResource(vd);
- free(rsc->p_sys);
+ free(sys->picsys);
return VLC_ENOMEM;
}
if (!surface) {
if (!sys->pool)
return VLC_EGENERIC;
- surface = sys->resource.p_sys->front_surface;
+ surface = sys->picsys->front_surface;
}
/* The new window dimensions should already have been computed by the
HRESULT hr = IDirectDrawSurface2_UpdateOverlay(surface,
&src, sys->display, &dst,
DDOVER_SHOW | DDOVER_KEYDESTOVERRIDE, &ddofx);
+ sys->restore_overlay = hr != DD_OK;
+
if (hr != DD_OK) {
msg_Warn(vd, "DirectDrawUpdateOverlay cannot move/resize overlay");
return VLC_EGENERIC;
sys->ch_wallpaper |= ch_wallpaper;
sys->wallpaper_requested = newval.b_bool;
vlc_mutex_unlock(&sys->lock);
-
- /* FIXME we should have a way to export variable to be saved */
- if (ch_wallpaper) {
- playlist_t *p_playlist = pl_Get(vd);
- /* Modify playlist as well because the vout might have to be
- * restarted */
- var_Create(p_playlist, "video-wallpaper", VLC_VAR_BOOL);
- var_SetBool(p_playlist, "video-wallpaper", newval.b_bool);
- }
return VLC_SUCCESS;
}
+typedef struct
+{
+ char **values;
+ char **descs;
+ size_t count;
+} enum_context_t;
+
/*****************************************************************************
* config variable callback
*****************************************************************************/
-static BOOL WINAPI DirectXEnumCallback2(GUID *guid, LPTSTR desc,
- LPTSTR drivername, VOID *context,
+static BOOL WINAPI DirectXEnumCallback2(GUID *guid, LPSTR desc,
+ LPSTR drivername, VOID *data,
HMONITOR hmon)
{
- VLC_UNUSED(guid); VLC_UNUSED(desc); VLC_UNUSED(hmon);
+ enum_context_t *ctx = data;
- module_config_t *item = context;
+ VLC_UNUSED(guid); VLC_UNUSED(desc); VLC_UNUSED(hmon);
- item->ppsz_list = xrealloc(item->ppsz_list,
- (item->i_list+2) * sizeof(char *));
- item->ppsz_list_text = xrealloc(item->ppsz_list_text,
- (item->i_list+2) * sizeof(char *));
+ char *psz_drivername = drivername;
+ ctx->values = xrealloc(ctx->values, (ctx->count + 1) * sizeof(char *));
+ ctx->descs = xrealloc(ctx->descs, (ctx->count + 1) * sizeof(char *));
- item->ppsz_list[item->i_list] = strdup(drivername);
- item->ppsz_list_text[item->i_list] = NULL;
- item->i_list++;
- item->ppsz_list[item->i_list] = NULL;
- item->ppsz_list_text[item->i_list] = NULL;
+ ctx->values[ctx->count] = strdup(psz_drivername);
+ ctx->descs[ctx->count] = strdup(psz_drivername);
+ ctx->count++;
return TRUE; /* Keep enumerating */
}
-static int FindDevicesCallback(vlc_object_t *object, char const *name,
- vlc_value_t newval, vlc_value_t oldval, void *data)
+static int FindDevicesCallback(vlc_object_t *object, const char *name,
+ char ***values, char ***descs)
{
- VLC_UNUSED(newval); VLC_UNUSED(oldval); VLC_UNUSED(data);
-
- module_config_t *item = config_FindConfig(object, name);
- if (!item)
- return VLC_SUCCESS;
-
- /* Clear-up the current list */
- if (item->i_list > 0) {
- int i;
- /* Keep the first entry */
- for (i = 1; i < item->i_list; i++) {
- free(item->ppsz_list[i]);
- free(item->ppsz_list_text[i]);
- }
- /* TODO: Remove when no more needed */
- item->ppsz_list[i] = NULL;
- item->ppsz_list_text[i] = NULL;
- }
- item->i_list = 1;
+ enum_context_t ctx;
+
+ ctx.values = xmalloc(sizeof(char *));
+ ctx.descs = xmalloc(sizeof(char *));
+ ctx.values[0] = strdup("");
+ ctx.descs[0] = strdup(_("Default"));
+ ctx.count = 1;
/* Load direct draw DLL */
HINSTANCE hddraw_dll = LoadLibrary(_T("DDRAW.DLL"));
- if (!hddraw_dll)
- return VLC_SUCCESS;
-
- /* Enumerate displays */
- HRESULT (WINAPI *OurDirectDrawEnumerateEx)(LPDDENUMCALLBACKEXA,
- LPVOID, DWORD) =
- (void *)GetProcAddress(hddraw_dll, _T("DirectDrawEnumerateExW"));
- if (OurDirectDrawEnumerateEx)
- OurDirectDrawEnumerateEx(DirectXEnumCallback2, item,
- DDENUM_ATTACHEDSECONDARYDEVICES);
-
- FreeLibrary(hddraw_dll);
+ if (hddraw_dll != NULL)
+ {
+ /* Enumerate displays */
+ HRESULT (WINAPI *OurDirectDrawEnumerateEx)(LPDDENUMCALLBACKEXA,
+ LPVOID, DWORD) =
+ (void *)GetProcAddress(hddraw_dll, DIRECTDRAWENUMERATEEX_NAME);
+ if (OurDirectDrawEnumerateEx != NULL)
+ OurDirectDrawEnumerateEx(DirectXEnumCallback2, &ctx,
+ DDENUM_ATTACHEDSECONDARYDEVICES);
+ FreeLibrary(hddraw_dll);
+ }
- /* Signal change to the interface */
- item->b_dirty = true;
+ VLC_UNUSED(object);
+ VLC_UNUSED(name);
- return VLC_SUCCESS;
+ *values = ctx.values;
+ *descs = ctx.descs;
+ return ctx.count;
}