]> git.sesse.net Git - vlc/blobdiff - modules/video_output/msw/directx.c
ios2: clean opengl buffers only in active state
[vlc] / modules / video_output / msw / directx.c
index 24526267e58c5139fbe1056fca915bded68f7ef8..4bae87d1a4b8c67a2c5e6afaf9ad959167b5f80f 100644 (file)
@@ -1,24 +1,24 @@
 /*****************************************************************************
  * 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.
  *****************************************************************************/
 
 /*****************************************************************************
@@ -43,6 +43,7 @@
 #include <vlc_plugin.h>
 #include <vlc_vout_display.h>
 #include <vlc_playlist.h>   /* needed for wallpaper */
+#include <vlc_charset.h>
 
 #include <windows.h>
 #include <winuser.h>
 #include "common.h"
 
 #ifdef UNICODE
-#   error "Unicode mode not supported"
+# warning "Unicode mode not tested"
 #endif
 
+#ifdef UNICODE
+# define DIRECTDRAWENUMERATEEX_NAME "DirectDrawEnumerateExW"
+#else
+# define DIRECTDRAWENUMERATEEX_NAME "DirectDrawEnumerateExA"
+#endif
+
+
 /*****************************************************************************
  * Module descriptor
  *****************************************************************************/
@@ -87,8 +95,8 @@
 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"))
@@ -103,7 +111,6 @@ vlc_module_begin()
               TRIPLEBUF_LONGTEXT, true)
     add_string("directx-device", "", DEVICE_TEXT, DEVICE_LONGTEXT, true)
         change_string_cb(FindDevicesCallback)
-        change_action_add(FindDevicesCallback, N_("Refresh list"))
 
     set_capability("vout display", 230)
     add_shortcut("directx")
@@ -447,12 +454,15 @@ static BOOL WINAPI DirectXOpenDDrawCallback(GUID *guid, LPTSTR desc,
     if (!hmon)
         return TRUE;
 
-    msg_Dbg(vd, "DirectXEnumCallback: %s, %s", desc, drivername);
+    char *psz_drivername = FromT(drivername);
+    char *psz_desc = FromT(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);
 
@@ -476,7 +486,7 @@ static BOOL WINAPI DirectXOpenDDrawCallback(GUID *guid, LPTSTR desc,
     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));
@@ -484,6 +494,8 @@ static BOOL WINAPI DirectXOpenDDrawCallback(GUID *guid, LPTSTR desc,
             *sys->display_driver = *guid;
     }
 
+    free(psz_drivername);
+    free(psz_desc);
     return TRUE;
 }
 /**
@@ -565,16 +577,16 @@ static int DirectXOpenDDraw(vout_display_t *vd)
     /* */
     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;
     }
 
     /* */
-    HRESULT (WINAPI *OurDirectDrawEnumerateEx)(LPDDENUMCALLBACKEXA, LPVOID, DWORD);
+    HRESULT (WINAPI *OurDirectDrawEnumerateEx)(LPDDENUMCALLBACKEX, LPVOID, DWORD);
     OurDirectDrawEnumerateEx =
-      (void *)GetProcAddress(sys->hddraw_dll, _T("DirectDrawEnumerateExA"));
+      (void *)GetProcAddress(sys->hddraw_dll, DIRECTDRAWENUMERATEEX_NAME);
 
     if (OurDirectDrawEnumerateEx) {
         char *device = var_GetString(vd, "directx-device");
@@ -1028,10 +1040,10 @@ static int DirectXCreatePictureResourceYuvOverlay(vout_display_t *vd,
     }
 
     /* */
-    picture_resource_t *rsc = &sys->resource;
-    rsc->p_sys->front_surface = front_surface;
-    rsc->p_sys->surface       = surface;
-    rsc->p_sys->fallback      = NULL;
+    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,
@@ -1084,10 +1096,10 @@ static int DirectXCreatePictureResourceYuv(vout_display_t *vd,
     }
 
     /* */
-    picture_resource_t *rsc = &sys->resource;
-    rsc->p_sys->front_surface = surface;
-    rsc->p_sys->surface       = surface;
-    rsc->p_sys->fallback      = NULL;
+    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,
@@ -1144,10 +1156,10 @@ static int DirectXCreatePictureResourceRgb(vout_display_t *vd,
     }
 
     /* */
-    picture_resource_t *rsc = &sys->resource;
-    rsc->p_sys->front_surface = surface;
-    rsc->p_sys->surface       = surface;
-    rsc->p_sys->fallback      = NULL;
+    picture_sys_t *picsys = sys->picsys;
+    picsys->front_surface = surface;
+    picsys->surface       = surface;
+    picsys->fallback      = NULL;
     return VLC_SUCCESS;
 }
 
@@ -1158,10 +1170,10 @@ static int DirectXCreatePictureResource(vout_display_t *vd,
     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 &&
@@ -1201,11 +1213,11 @@ static void DirectXDestroyPictureResource(vout_display_t *vd)
 {
     vout_display_sys_t *sys = vd->sys;
 
-    if (sys->resource.p_sys->front_surface != sys->resource.p_sys->surface)
-        DirectXDestroySurface(sys->resource.p_sys->surface);
-    DirectXDestroySurface(sys->resource.p_sys->front_surface);
-    if (sys->resource.p_sys->fallback)
-        picture_Release(sys->resource.p_sys->fallback);
+    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)
@@ -1236,16 +1248,11 @@ static int DirectXCreatePool(vout_display_t *vd,
         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;
     }
 
@@ -1314,7 +1321,7 @@ static int DirectXUpdateOverlay(vout_display_t *vd, LPDIRECTDRAWSURFACE2 surface
     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
@@ -1405,70 +1412,67 @@ static int WallpaperCallback(vlc_object_t *object, char const *cmd,
     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,
+                                        LPTSTR 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 = FromT(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] = psz_drivername;
+    ctx->descs[ctx->count] = psz_drivername;
+    ctx->count++;
 
+    free(psz_drivername);
     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("DirectDrawEnumerateExA"));
-    if (OurDirectDrawEnumerateEx)
-        OurDirectDrawEnumerateEx(DirectXEnumCallback2, item,
-                                 DDENUM_ATTACHEDSECONDARYDEVICES);
+    if (hddraw_dll != NULL)
+    {
+        /* Enumerate displays */
+        HRESULT (WINAPI *OurDirectDrawEnumerateEx)(LPDDENUMCALLBACKEX,
+                                                   LPVOID, DWORD) =
+              (void *)GetProcAddress(hddraw_dll, DIRECTDRAWENUMERATEEX_NAME);
+        if (OurDirectDrawEnumerateEx != NULL)
+            OurDirectDrawEnumerateEx(DirectXEnumCallback2, &ctx,
+                                     DDENUM_ATTACHEDSECONDARYDEVICES);
+        FreeLibrary(hddraw_dll);
+    }
 
-    FreeLibrary(hddraw_dll);
+    VLC_UNUSED(object);
+    VLC_UNUSED(name);
 
-    return VLC_SUCCESS;
+    *values = ctx.values;
+    *descs = ctx.descs;
+    return ctx.count;
 }