[VFW] Add support for video compressor/decompressor dynamic installation

Christian Costa titan.costa at wanadoo.fr
Sun Jun 29 04:53:30 CDT 2003


Hi,

This patch adds support for video compressor/decompressor dynamic 
installation (through ICInstall).
This makes the game Schizm work and play mpeg video.

Bye,
Christian.

Changelog :
Add support for video compressor/decompressor dynamic installation.

Christian Costa   titan.costa at wanadoo.fr

-------------- next part --------------
Index: msvfw32.spec
===================================================================
RCS file: /home/wine/wine/dlls/msvideo/msvfw32.spec,v
retrieving revision 1.17
diff -u -r1.17 msvfw32.spec
--- msvfw32.spec	23 Jun 2003 03:33:25 -0000	1.17
+++ msvfw32.spec	29 Jun 2003 09:23:57 -0000
@@ -34,12 +34,12 @@
 @ stdcall ICImageCompress(long long ptr ptr ptr long ptr)
 @ stdcall ICImageDecompress(long long ptr ptr ptr)
 @ stdcall ICInfo(long long ptr)
-@ stub    ICInstall
+@ stdcall ICInstall(long long ptr str long)
 @ stdcall ICLocate(long long ptr ptr long)
 @ stub    ICMThunk
 @ stdcall ICOpen(long long long)
 @ stdcall ICOpenFunction(long long long ptr)
-@ stub    ICRemove
+@ stdcall ICRemove(long long long)
 @ stdcall ICSendMessage(long long long long)
 @ stub    ICSeqCompressFrame
 @ stub    ICSeqCompressFrameEnd
Index: msvideo_main.c
===================================================================
RCS file: /home/wine/wine/dlls/msvideo/msvideo_main.c,v
retrieving revision 1.49
diff -u -r1.49 msvideo_main.c
--- msvideo_main.c	23 Jun 2003 03:33:25 -0000	1.49
+++ msvideo_main.c	29 Jun 2003 09:24:01 -0000
@@ -47,6 +47,35 @@
 
 static WINE_HIC*        MSVIDEO_FirstHic /* = NULL */;
 
+typedef struct _reg_driver reg_driver;
+struct _reg_driver{
+	DWORD fccType;
+	DWORD fccHandler;
+	DRIVERPROC proc;
+	char* name;
+	reg_driver* next;
+};
+
+static reg_driver* reg_driver_list = NULL;
+
+static int compare_fourcc(DWORD fcc1, DWORD fcc2)
+{
+  char fcc_str1[5];
+  char fcc_str2[5];
+  fcc_str1[0] = LOBYTE(LOWORD(fcc1));
+  fcc_str1[1] = HIBYTE(LOWORD(fcc1));
+  fcc_str1[2] = LOBYTE(HIWORD(fcc1));
+  fcc_str1[3] = HIBYTE(HIWORD(fcc1));
+  fcc_str1[4] = 0;
+  fcc_str2[0] = LOBYTE(LOWORD(fcc2));
+  fcc_str2[1] = HIBYTE(LOWORD(fcc2));
+  fcc_str2[2] = LOBYTE(HIWORD(fcc2));
+  fcc_str2[3] = HIBYTE(HIWORD(fcc2));
+  fcc_str2[4] = 0;
+
+  return strcasecmp(fcc_str1,fcc_str2);
+}
+
 /******************************************************************
  *		MSVIDEO_GetHicPtr
  *
@@ -130,6 +159,88 @@
 static DWORD IC_HandleRef = 1;
 
 /***********************************************************************
+ *		ICInstall			[MSVFW32.@]
+ */
+BOOL VFWAPI ICInstall(DWORD fccType, DWORD fccHandler, LPARAM lParam, LPSTR szDesc, UINT wFlags) 
+{
+    reg_driver* driver;
+
+    TRACE("(%s,%s,%p,%p,0x%08x)\n", wine_dbgstr_fcc(fccType), wine_dbgstr_fcc(fccHandler), (void*)lParam, szDesc, wFlags);
+
+    /* Check if a driver is already registered */
+    driver = reg_driver_list;
+    while(driver)
+        if (!compare_fourcc(fccType, driver->fccType) &&
+            !compare_fourcc(fccHandler, driver->fccHandler))
+            break;
+        else
+            driver = driver->next;
+    if (driver)
+        return FALSE;
+
+    /* Register the driver */
+    driver = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(reg_driver));
+    driver->fccType = fccType;
+    driver->fccHandler = fccHandler;
+
+    switch(wFlags) {
+    case ICINSTALL_FUNCTION:
+        driver->proc = (DRIVERPROC)lParam;
+	driver->name = NULL;
+        break;
+    case ICINSTALL_DRIVER:
+	driver->proc = NULL;
+	driver->name = HeapAlloc(GetProcessHeap(), 0, strlen((char*)lParam));
+	strcpy(driver->name, (char*) lParam);
+	break;
+    default:
+	ERR("Invalid flags!\n");
+	HeapFree(GetProcessHeap(), 0, driver);
+	return FALSE;
+   }
+
+   /* Insert our driver in the list*/
+   driver->next = reg_driver_list;
+   reg_driver_list = driver;
+    
+   return TRUE;
+}
+
+/***********************************************************************
+ *		ICRemove			[MSVFW32.@]
+ */
+BOOL VFWAPI ICRemove(DWORD fccType, DWORD fccHandler, UINT wFlags) 
+{
+    reg_driver* driver;
+    reg_driver** previous;
+    
+    TRACE("(%s,%s,0x%08x)\n", wine_dbgstr_fcc(fccType), wine_dbgstr_fcc(fccHandler), wFlags);
+
+    /* Check if a driver is already registered */
+    driver = reg_driver_list;
+    previous = &reg_driver_list;
+    while(driver)
+        if (!compare_fourcc(fccType, driver->fccType) &&
+            !compare_fourcc(fccHandler, driver->fccHandler))
+            break;
+        else {
+            previous = &(driver->next);
+            driver = driver->next;
+        }
+    if (!driver)
+        return FALSE;
+
+    /* Remove the driver from the list */
+    *previous = driver->next;
+    if (driver->name)
+        HeapFree(GetProcessHeap(), 0, driver->name);
+    HeapFree(GetProcessHeap(), 0, driver);
+    
+    return TRUE;  
+}
+
+
+/***********************************************************************
  *		ICOpen				[MSVFW32.@]
  * Opens an installable compressor. Return special handle.
  */
@@ -140,20 +251,23 @@
     HDRVR		hdrv;
     WINE_HIC*           whic;
     BOOL                bIs16;
+    reg_driver*         driver;
 
     TRACE("(%s,%s,0x%08x)\n", wine_dbgstr_fcc(fccType), wine_dbgstr_fcc(fccHandler), wMode);
 
-    codecname[0] = LOBYTE(LOWORD(fccType));
-    codecname[1] = HIBYTE(LOWORD(fccType));
-    codecname[2] = LOBYTE(HIWORD(fccType));
-    codecname[3] = HIBYTE(HIWORD(fccType));
-    codecname[4] = '.';
-    codecname[5] = LOBYTE(LOWORD(fccHandler));
-    codecname[6] = HIBYTE(LOWORD(fccHandler));
-    codecname[7] = LOBYTE(HIWORD(fccHandler));
-    codecname[8] = HIBYTE(HIWORD(fccHandler));
-    codecname[9] = '\0';
-
+    /* Check if there is a registered driver that matches */
+    driver = reg_driver_list;
+    while(driver)
+        if (!compare_fourcc(fccType, driver->fccType) &&
+            !compare_fourcc(fccHandler, driver->fccHandler))
+	    break;
+        else
+            driver = driver->next;
+
+    if (driver && driver->proc)
+	/* The driver has been registered at runtime with its driverproc */
+        return MSVIDEO_OpenFunction(fccType, fccHandler, wMode, (DRIVERPROC)driver->proc, (DWORD)NULL);
+  
     /* Well, lParam2 is in fact a LPVIDEO_OPEN_PARMS, but it has the
      * same layout as ICOPEN
      */
@@ -166,22 +280,41 @@
     icopen.pV1Reserved          = NULL;
     icopen.pV2Reserved          = NULL;
     icopen.dnDevNode            = 0; /* FIXME */
-        
-    hdrv = OpenDriverA(codecname, "drivers32", (LPARAM)&icopen);
-    if (!hdrv) 
-    {
-        if (fccType == streamtypeVIDEO) 
-        {
-            codecname[0] = 'v';
-            codecname[1] = 'i';
-            codecname[2] = 'd';
-            codecname[3] = 'c';
+	
+    if (!driver) {
+        /* The driver is registered in the registry */
+        codecname[0] = LOBYTE(LOWORD(fccType));
+        codecname[1] = HIBYTE(LOWORD(fccType));
+        codecname[2] = LOBYTE(HIWORD(fccType));
+        codecname[3] = HIBYTE(HIWORD(fccType));
+        codecname[4] = '.';
+        codecname[5] = LOBYTE(LOWORD(fccHandler));
+        codecname[6] = HIBYTE(LOWORD(fccHandler));
+        codecname[7] = LOBYTE(HIWORD(fccHandler));
+        codecname[8] = HIBYTE(HIWORD(fccHandler));
+        codecname[9] = '\0';
 
-            fccType = ICTYPE_VIDEO;
-            hdrv = OpenDriverA(codecname, "drivers32", (LPARAM)&icopen);
-        }
-        if (!hdrv)
-            return 0;
+        hdrv = OpenDriverA(codecname, "drivers32", (LPARAM)&icopen);
+        if (!hdrv) 
+        {
+            if (fccType == streamtypeVIDEO) 
+            {
+                codecname[0] = 'v';
+                codecname[1] = 'i';
+                codecname[2] = 'd';
+                codecname[3] = 'c';
+
+		fccType = ICTYPE_VIDEO;
+                hdrv = OpenDriverA(codecname, "drivers32", (LPARAM)&icopen);   
+	    }
+            if (!hdrv)
+                return 0;
+	}
+    } else {
+        /* The driver has been registered at runtime with its name */
+        hdrv = OpenDriverA(driver->name, NULL, (LPARAM)&icopen);
+        if (!hdrv) 
+            return 0; 
     }
     bIs16 = GetDriverFlags(hdrv) & WINE_GDF_16BIT;
 
@@ -256,9 +389,11 @@
     /* return value is not checked */
     MSVIDEO_SendMessage(whic, DRV_ENABLE, 0L, 0L);
 
-    whic->hdrv = (HDRVR)MSVIDEO_SendMessage(whic, DRV_OPEN, 0, (DWORD)&icopen);
-
-    if (whic->hdrv == 0) 
+    whic->driverId = (DWORD)MSVIDEO_SendMessage(whic, DRV_OPEN, 0, (DWORD)&icopen);
+    /* FIXME: What should we put here? */
+    whic->hdrv = (HDRVR)0;
+    
+    if (whic->driverId == 0) 
     {
         WARN("DRV_OPEN failed for hic %p\n", whic->hic);
         MSVIDEO_FirstHic = whic->next;
@@ -621,7 +756,8 @@
 #undef XX
     
     if (whic->driverproc) {
-        ret = whic->driverproc((DWORD)whic->hic, whic->hdrv, msg, lParam1, lParam2);
+	/* dwDriverId parameter is the value returned by the DRV_OPEN */
+        ret = whic->driverproc(whic->driverId, whic->hdrv, msg, lParam1, lParam2);
     } else {
         ret = SendDriverMessage(whic->hdrv, msg, lParam1, lParam2);
     }
Index: msvideo_private.h
===================================================================
RCS file: /home/wine/wine/dlls/msvideo/msvideo_private.h,v
retrieving revision 1.5
diff -u -r1.5 msvideo_private.h
--- msvideo_private.h	23 Jun 2003 03:33:25 -0000	1.5
+++ msvideo_private.h	29 Jun 2003 09:24:01 -0000
@@ -40,6 +40,7 @@
 					/* 26: */
     DWORD               driverproc16;   /* Wine specific flags */
     HIC                 hic;
+    DWORD               driverId;
     struct tagWINE_HIC* next;
 } WINE_HIC;
 


More information about the wine-patches mailing list