summaryrefslogtreecommitdiffstats
path: root/loader
diff options
context:
space:
mode:
Diffstat (limited to 'loader')
-rw-r--r--loader/dshow/DS_Filter.c7
-rw-r--r--loader/dshow/allocator.c8
-rw-r--r--loader/dshow/graph.c163
-rw-r--r--loader/dshow/graph.h57
-rw-r--r--loader/dshow/guids.c4
-rw-r--r--loader/dshow/guids.h2
-rw-r--r--loader/dshow/interfaces.h28
-rw-r--r--loader/qtx/qtxsdk/components.h6
-rw-r--r--loader/win32.c196
9 files changed, 431 insertions, 40 deletions
diff --git a/loader/dshow/DS_Filter.c b/loader/dshow/DS_Filter.c
index e3102cf264..693d59c25f 100644
--- a/loader/dshow/DS_Filter.c
+++ b/loader/dshow/DS_Filter.c
@@ -5,6 +5,7 @@
#include "config.h"
#include "DS_Filter.h"
+#include "graph.h"
#include "loader/drv.h"
#include "loader/com.h"
#include <stdio.h>
@@ -125,6 +126,7 @@ DS_Filter* DS_FilterCreate(const char* dllname, const GUID* id,
// char eb[250];
const char* em = NULL;
MemAllocator* tempAll;
+ FilterGraph* graph;
ALLOCATOR_PROPERTIES props,props1;
DS_Filter* This = malloc(sizeof(DS_Filter));
if (!This)
@@ -166,6 +168,7 @@ DS_Filter* DS_FilterCreate(const char* dllname, const GUID* id,
ULONG fetched;
HRESULT result;
unsigned int i;
+ static const uint16_t filter_name[] = { 'F', 'i', 'l', 't', 'e', 'r', 0 };
This->m_iHandle = LoadLibraryA(dllname);
if (!This->m_iHandle)
@@ -199,6 +202,10 @@ DS_Filter* DS_FilterCreate(const char* dllname, const GUID* id,
em = "object does not provide IBaseFilter interface";
break;
}
+
+ graph = FilterGraphCreate();
+ result = This->m_pFilter->vt->JoinFilterGraph(This->m_pFilter, (IFilterGraph*)graph, filter_name);
+
// enumerate pins
result = This->m_pFilter->vt->EnumPins(This->m_pFilter, &enum_pins);
if (result || !enum_pins)
diff --git a/loader/dshow/allocator.c b/loader/dshow/allocator.c
index b75f1bebfb..a90bd9d3d2 100644
--- a/loader/dshow/allocator.c
+++ b/loader/dshow/allocator.c
@@ -116,7 +116,7 @@ static inline avm_list_t* avm_list_find(avm_list_t* head, void* member)
static long MemAllocator_CreateAllocator(GUID* clsid, const GUID* iid, void** ppv)
{
- IMemAllocator* p;
+ IUnknown* p;
int result;
if (!ppv)
return -1;
@@ -124,9 +124,9 @@ static long MemAllocator_CreateAllocator(GUID* clsid, const GUID* iid, void** pp
if (memcmp(clsid, &CLSID_MemoryAllocator, sizeof(GUID)))
return -1;
- p = (IMemAllocator*) MemAllocatorCreate();
- result = p->vt->QueryInterface((IUnknown*)p, iid, ppv);
- p->vt->Release((IUnknown*)p);
+ p = (IUnknown*) MemAllocatorCreate();
+ result = p->vt->QueryInterface(p, iid, ppv);
+ p->vt->Release(p);
return result;
}
diff --git a/loader/dshow/graph.c b/loader/dshow/graph.c
new file mode 100644
index 0000000000..01bf6c7253
--- /dev/null
+++ b/loader/dshow/graph.c
@@ -0,0 +1,163 @@
+/*
+ * Implemention of FilterGraph. Based on allocator.c.
+ * Copyright 2010 Steinar H. Gunderson
+ *
+ * This file is part of MPlayer.
+ *
+ * MPlayer 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
+ * (at your option) any later version.
+ *
+ * MPlayer 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.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with MPlayer; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Modified for use with MPlayer, detailed changelog at
+ * http://svn.mplayerhq.hu/mplayer/trunk/
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "config.h"
+#include "loader/com.h"
+#include "loader/dshow/graph.h"
+#include "loader/wine/winerror.h"
+
+// How many FilterGraph objects exist.
+// Used for knowing when to register and unregister the class in COM.
+static int GraphKeeper = 0;
+
+static long FilterGraph_CreateGraph(GUID* clsid, const GUID* iid, void** ppv)
+{
+ IUnknown* p;
+ int result;
+ if (!ppv)
+ return -1;
+ *ppv = 0;
+ if (memcmp(clsid, &CLSID_FilterGraph, sizeof(*clsid)))
+ return -1;
+
+ p = (IUnknown*) FilterGraphCreate();
+ result = p->vt->QueryInterface(p, iid, ppv);
+ p->vt->Release(p);
+
+ return result;
+}
+
+static void FilterGraph_Destroy(FilterGraph* This)
+{
+ Debug printf("FilterGraph_Destroy(%p) called (%d, %d)\n", This, This->refcount, GraphKeeper);
+#ifdef WIN32_LOADER
+ if (--GraphKeeper == 0)
+ UnregisterComClass(&CLSID_FilterGraph, FilterGraph_CreateGraph);
+#endif
+ free(This->vt);
+ free(This);
+}
+
+HRESULT STDCALL FilterGraph_AddFilter(FilterGraph* This,
+ IBaseFilter* pFilter,
+ unsigned short* pName)
+{
+ Debug printf("FilterGraph_AddFilter(%p) called\n", This);
+ return E_NOTIMPL;
+}
+
+HRESULT STDCALL FilterGraph_RemoveFilter(FilterGraph* This, IBaseFilter* pFilter)
+{
+ Debug printf("FilterGraph_RemoveFilter(%p) called\n", This);
+ return E_NOTIMPL;
+}
+
+HRESULT STDCALL FilterGraph_EnumFilters(FilterGraph* This, IEnumFilters** ppEnum)
+{
+ Debug printf("FilterGraph_EnumFilters(%p) called\n", This);
+ return E_NOTIMPL;
+}
+
+HRESULT STDCALL FilterGraph_FindFilterByName(FilterGraph* This,
+ unsigned short* pName,
+ IBaseFilter** ppFilter)
+{
+ Debug printf("FilterGraph_FindFilterByName(%p) called\n", This);
+ return E_NOTIMPL;
+}
+
+HRESULT STDCALL FilterGraph_ConnectDirect(FilterGraph* This,
+ IPin* ppinOut,
+ IPin* ppinIn,
+ const AM_MEDIA_TYPE* pmt)
+{
+ Debug printf("FilterGraph_ConnectDirect(%p) called\n", This);
+ return E_NOTIMPL;
+}
+
+HRESULT STDCALL FilterGraph_Reconnect(FilterGraph* This, IPin* ppin)
+{
+ Debug printf("FilterGraph_Reconnect(%p) called\n", This);
+ return E_NOTIMPL;
+}
+
+HRESULT STDCALL FilterGraph_Disconnect(FilterGraph* This, IPin* ppin)
+{
+ Debug printf("FilterGraph_Disconnect(%p) called\n", This);
+ return E_NOTIMPL;
+}
+
+HRESULT STDCALL FilterGraph_SetDefaultSyncSource(FilterGraph* This)
+{
+ Debug printf("FilterGraph_SetDefaultSyncSource(%p) called\n", This);
+ return E_NOTIMPL;
+}
+
+IMPLEMENT_IUNKNOWN(FilterGraph)
+
+FilterGraph* FilterGraphCreate()
+{
+ FilterGraph* This = calloc(1, sizeof(*This));
+
+ if (!This)
+ return NULL;
+
+ Debug printf("FilterGraphCreate() called -> %p\n", This);
+
+ This->refcount = 1;
+
+ This->vt = calloc(1, sizeof(*This->vt));
+
+ if (!This->vt) {
+ free(This);
+ return NULL;
+ }
+
+ This->vt->QueryInterface = FilterGraph_QueryInterface;
+ This->vt->AddRef = FilterGraph_AddRef;
+ This->vt->Release = FilterGraph_Release;
+
+ This->vt->AddFilter = FilterGraph_AddFilter;
+ This->vt->RemoveFilter = FilterGraph_RemoveFilter;
+ This->vt->EnumFilters = FilterGraph_EnumFilters;
+ This->vt->FindFilterByName = FilterGraph_FindFilterByName;
+ This->vt->ConnectDirect = FilterGraph_ConnectDirect;
+ This->vt->Reconnect = FilterGraph_Reconnect;
+ This->vt->Disconnect = FilterGraph_Disconnect;
+ This->vt->SetDefaultSyncSource = FilterGraph_SetDefaultSyncSource;
+
+ This->interfaces[0] = IID_IUnknown;
+ This->interfaces[1] = IID_IFilterGraph;
+
+#ifdef WIN32_LOADER
+ if (GraphKeeper++ == 0)
+ RegisterComClass(&CLSID_FilterGraph, FilterGraph_CreateGraph);
+#endif
+
+ return This;
+}
+
diff --git a/loader/dshow/graph.h b/loader/dshow/graph.h
new file mode 100644
index 0000000000..7667f5a39e
--- /dev/null
+++ b/loader/dshow/graph.h
@@ -0,0 +1,57 @@
+#ifndef MPLAYER_GRAPH_H
+#define MPLAYER_GRAPH_H
+
+/*
+ * Copyright 2010 Steinar H. Gunderson
+ *
+ * This file is part of MPlayer.
+ *
+ * MPlayer 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
+ * (at your option) any later version.
+ *
+ * MPlayer 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.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with MPlayer; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include "interfaces.h"
+#include "cmediasample.h"
+
+typedef struct FilterGraph FilterGraph;
+
+struct FilterGraph {
+ IFilterGraph_vt* vt;
+ DECLARE_IUNKNOWN();
+ GUID interfaces[2];
+
+ HRESULT STDCALL (*AddFilter)(FilterGraph* This,
+ /* [in] */ IBaseFilter* pFilter,
+ /* [string][in] */ unsigned short* pName);
+ HRESULT STDCALL (*RemoveFilter)(FilterGraph* This,
+ /* [in] */ IBaseFilter* pFilter);
+ HRESULT STDCALL (*EnumFilters)(FilterGraph* This,
+ /* [out] */ IEnumFilters** ppEnum);
+ HRESULT STDCALL (*FindFilterByName)(FilterGraph* This,
+ /* [string][in] */ unsigned short* pName,
+ /* [out] */ IBaseFilter** ppFilter);
+ HRESULT STDCALL (*ConnectDirect)(FilterGraph* This,
+ /* [in] */ IPin* ppinOut,
+ /* [in] */ IPin* ppinIn,
+ /* [in] */ const AM_MEDIA_TYPE* pmt);
+ HRESULT STDCALL (*Reconnect)(FilterGraph* This,
+ /* [in] */ IPin* ppin);
+ HRESULT STDCALL (*Disconnect)(FilterGraph* This,
+ /* [in] */ IPin* ppin);
+ HRESULT STDCALL (*SetDefaultSyncSource)(FilterGraph* This);
+};
+
+FilterGraph* FilterGraphCreate(void);
+
+#endif /* MPLAYER_GRAPH_H */
diff --git a/loader/dshow/guids.c b/loader/dshow/guids.c
index 73cf7f5456..5d793bb14d 100644
--- a/loader/dshow/guids.c
+++ b/loader/dshow/guids.c
@@ -11,6 +11,8 @@ const GUID IID_IBaseFilter={0x56a86895, 0x0ad4, 0x11ce,
{0xb0, 0x3a, 0x00, 0x20, 0xaf, 0x0b, 0xa7, 0x70}};
const GUID IID_IEnumPins={0x56a86892, 0x0ad4, 0x11ce,
{0xb0, 0x3a, 0x00, 0x20, 0xaf, 0x0b, 0xa7, 0x70}};
+const GUID IID_IFilterGraph={0x56a8689f, 0x0ad4, 0x11ce,
+ {0xb0, 0x3a, 0x00, 0x20, 0xaf, 0x0b, 0xa7, 0x70}};
const GUID IID_IEnumMediaTypes={0x89c31040, 0x846b, 0x11ce,
{0x97, 0xd3, 0x00, 0xaa, 0x00, 0x55, 0x59, 0x5a}};
const GUID IID_IMemInputPin={0x56a8689d, 0x0ad4, 0x11ce,
@@ -64,6 +66,8 @@ const GUID MEDIASUBTYPE_I420={0x30323449, 0x0000, 0x0010,
{0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}};
const GUID MEDIASUBTYPE_IF09={0x39304649, 0x0000, 0x0010,
{0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}};
+const GUID CLSID_FilterGraph={0xe436ebb3, 0x524f, 0x11ce,
+ {0x9f, 0x53, 0x00, 0x20, 0xaf, 0x0b, 0xa7, 0x70}};
const GUID CLSID_MemoryAllocator={0x1e651cc0, 0xb199, 0x11d0,
{0x82, 0x12, 0x00, 0xc0, 0x4f, 0xc3, 0x2c, 0x45}};
const GUID IID_DivxHidden={0x598eba01, 0xb49a, 0x11d2,
diff --git a/loader/dshow/guids.h b/loader/dshow/guids.h
index 80686558b4..76a4970d27 100644
--- a/loader/dshow/guids.h
+++ b/loader/dshow/guids.h
@@ -46,6 +46,7 @@ typedef GUID IID;
extern const GUID IID_IBaseFilter;
extern const GUID IID_IEnumPins;
extern const GUID IID_IEnumMediaTypes;
+extern const GUID IID_IFilterGraph;
extern const GUID IID_IMemInputPin;
extern const GUID IID_IMemAllocator;
extern const GUID IID_IMediaSample;
@@ -54,6 +55,7 @@ extern const GUID IID_Iv50Hidden;
extern const GUID CLSID_DivxDecompressorCF;
extern const GUID IID_IDivxFilterInterface;
extern const GUID CLSID_IV50_Decoder;
+extern const GUID CLSID_FilterGraph;
extern const GUID CLSID_MemoryAllocator;
extern const GUID MEDIATYPE_Video;
// avoid a clash with MinGW-W64 libuuid
diff --git a/loader/dshow/interfaces.h b/loader/dshow/interfaces.h
index 5c927a55be..af9544ada5 100644
--- a/loader/dshow/interfaces.h
+++ b/loader/dshow/interfaces.h
@@ -329,4 +329,32 @@ struct IDivxFilterInterface_vt
HRESULT STDCALL ( *get_AspectRatio )(IDivxFilterInterface* This, int* x, IDivxFilterInterface* Thisit, int* y);
};
+typedef struct IEnumFilters IEnumFilters;
+
+typedef struct IFilterGraph_vt
+{
+ INHERIT_IUNKNOWN();
+
+ HRESULT STDCALL ( *AddFilter )(IFilterGraph* This,
+ /* [in] */ IBaseFilter* pFilter,
+ /* [string][in] */ unsigned short* pName);
+ HRESULT STDCALL ( *RemoveFilter )(IFilterGraph* This,
+ /* [in] */ IBaseFilter* pFilter);
+ HRESULT STDCALL ( *EnumFilters )(IFilterGraph* This,
+ /* [out] */ IEnumFilters** ppEnum);
+ HRESULT STDCALL ( *FindFilterByName )(IFilterGraph* This,
+ /* [string][in] */ unsigned short* pName,
+ /* [out] */ IBaseFilter** ppFilter);
+ HRESULT STDCALL ( *ConnectDirect )(IFilterGraph* This,
+ /* [in] */ IPin* ppinOut,
+ /* [in] */ IPin* ppinIn,
+ /* [in] */ const AM_MEDIA_TYPE* pmt);
+ HRESULT STDCALL ( *Reconnect )(IFilterGraph* This,
+ /* [in] */ IPin* ppin);
+ HRESULT STDCALL ( *Disconnect )(IFilterGraph* This,
+ /* [in] */ IPin* ppin);
+ HRESULT STDCALL ( *SetDefaultSyncSource )(IFilterGraph* This);
+} IFilterGraph_vt;
+struct IFilterGraph { IFilterGraph_vt *vt; };
+
#endif /*MPLAYER_INTERFACES_H */
diff --git a/loader/qtx/qtxsdk/components.h b/loader/qtx/qtxsdk/components.h
index 08b883099c..2e42a0412f 100644
--- a/loader/qtx/qtxsdk/components.h
+++ b/loader/qtx/qtxsdk/components.h
@@ -12,7 +12,7 @@ typedef unsigned char Boolean;
typedef unsigned char Str31[32];
typedef int32_t Fixed;
-typedef int32_t OSErr;
+typedef int16_t OSErr;
typedef int OSType;
typedef int32_t ComponentResult;
@@ -641,10 +641,10 @@ static inline void dump_ImageDescription(void* xxx){
printf("=============== ImageDescription at %p ==================\n",xxx);
printf("idSize=0x%X fourcc=0x%08X\n",id->idSize,id->cType);
printf("ver=%d rev=%d vendor=0x%08X\n",id->version,id->revisionLevel,id->vendor);
- printf("tempQ=%d spatQ=%d dim: %d x %d dpi: %d x %d depth: %d\n",
+ printf("tempQ=%d spatQ=%d dim: %d x %d dpi: %.2f x %.2f depth: %d\n",
id->temporalQuality,id->spatialQuality,
id->width, id->height,
- id->hRes, id->vRes,
+ id->hRes / 65536.0, id->vRes / 65536.0,
id->depth);
printf("dataSize=%d frameCount=%d clutID=%d\n",id->dataSize, id->frameCount, id->clutID);
printf("name='%.*s'\n",((char*)(&id->name))[0],((char*)(&id->name))+1);
diff --git a/loader/win32.c b/loader/win32.c
index 08985a28e1..d540e6dfe2 100644
--- a/loader/win32.c
+++ b/loader/win32.c
@@ -240,6 +240,7 @@ typedef struct th_list_t{
//static int heap_counter=0;
static tls_t* g_tls=NULL;
static th_list* list=NULL;
+static pthread_mutex_t list_lock = PTHREAD_MUTEX_INITIALIZER;
#if 0
static void test_heap(void)
@@ -638,6 +639,7 @@ static void* WINAPI expCreateThread(void* pSecAttr, long dwStackSize,
printf( "WARNING: CreateThread flags not supported\n");
if(dwThreadId)
*dwThreadId=(long)pth;
+ pthread_mutex_lock(&list_lock);
if(list==NULL)
{
list=my_mreq(sizeof(th_list), 1);
@@ -651,11 +653,19 @@ static void* WINAPI expCreateThread(void* pSecAttr, long dwStackSize,
list=list->next;
}
list->thread=pth;
+ pthread_mutex_unlock(&list_lock);
dbgprintf("CreateThread(0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x) => 0x%x\n",
pSecAttr, dwStackSize, lpStartAddress, lpParameter, dwFlags, dwThreadId, pth);
return pth;
}
+static DWORD WINAPI expResumeThread(HANDLE hThread)
+{
+ int ret = 1;
+ dbgprintf("ResumeThread(0x%x) => 0x%x\n", hThread, ret);
+ return ret;
+}
+
struct mutex_list_t;
struct mutex_list_t
@@ -667,14 +677,18 @@ struct mutex_list_t
char reset;
char name[128];
int semaphore;
+ int lock_count;
+ pthread_t owner;
struct mutex_list_t* next;
struct mutex_list_t* prev;
};
typedef struct mutex_list_t mutex_list;
static mutex_list* mlist=NULL;
+static pthread_mutex_t mlist_lock = PTHREAD_MUTEX_INITIALIZER;
void destroy_event(void* event)
{
+ pthread_mutex_lock(&mlist_lock);
mutex_list* pp=mlist;
// printf("garbage collector: destroy_event(%x)\n", event);
while(pp)
@@ -696,10 +710,12 @@ void destroy_event(void* event)
}
printf("0\n");
*/
+ pthread_mutex_unlock(&mlist_lock);
return;
}
pp=pp->prev;
}
+ pthread_mutex_unlock(&mlist_lock);
}
static void* WINAPI expCreateEventA(void* pSecAttr, char bManualReset,
@@ -707,6 +723,7 @@ static void* WINAPI expCreateEventA(void* pSecAttr, char bManualReset,
{
pthread_mutex_t *pm;
pthread_cond_t *pc;
+ void *ret;
/*
mutex_list* pp;
pp=mlist;
@@ -717,6 +734,7 @@ static void* WINAPI expCreateEventA(void* pSecAttr, char bManualReset,
}
printf("0\n");
*/
+ pthread_mutex_lock(&mlist_lock);
if(mlist!=NULL)
{
mutex_list* pp=mlist;
@@ -727,6 +745,7 @@ static void* WINAPI expCreateEventA(void* pSecAttr, char bManualReset,
{
dbgprintf("CreateEventA(0x%x, 0x%x, 0x%x, 0x%x='%s') => 0x%x\n",
pSecAttr, bManualReset, bInitialState, name, name, pp->pm);
+ pthread_mutex_unlock(&mlist_lock);
return pp->pm;
}
}while((pp=pp->prev) != NULL);
@@ -768,7 +787,9 @@ static void* WINAPI expCreateEventA(void* pSecAttr, char bManualReset,
else
dbgprintf("CreateEventA(0x%x, 0x%x, 0x%x, NULL) => 0x%x\n",
pSecAttr, bManualReset, bInitialState, mlist);
- return mlist;
+ ret = mlist;
+ pthread_mutex_unlock(&mlist_lock);
+ return ret;
}
static void* WINAPI expSetEvent(void* event)
@@ -800,8 +821,8 @@ static void* WINAPI expWaitForSingleObject(void* object, int duration)
mutex_list *ml = (mutex_list *)object;
// FIXME FIXME FIXME - this value is sometime unititialize !!!
int ret = WAIT_FAILED;
- mutex_list* pp=mlist;
- th_list* tp=list;
+ mutex_list* pp;
+ th_list* tp;
if(object == (void*)0xcfcf9898)
{
/**
@@ -818,8 +839,11 @@ static void* WINAPI expWaitForSingleObject(void* object, int duration)
dbgprintf("WaitForSingleObject(0x%x, duration %d) =>\n",object, duration);
// See if this is a thread.
+ pthread_mutex_lock(&list_lock);
+ tp=list;
while (tp && (tp->thread != object))
tp = tp->prev;
+ pthread_mutex_unlock(&list_lock);
if (tp) {
if (pthread_join(*(pthread_t*)object, NULL) == 0) {
return (void*)WAIT_OBJECT_0;
@@ -832,8 +856,11 @@ static void* WINAPI expWaitForSingleObject(void* object, int duration)
// this object really exists in our list
if (!ml)
return (void*) ret;
+ pthread_mutex_lock(&mlist_lock);
+ pp=mlist;
while (pp && (pp->pm != ml->pm))
pp = pp->prev;
+ pthread_mutex_unlock(&mlist_lock);
if (!pp) {
dbgprintf("WaitForSingleObject: NotFound\n");
return (void*)ret;
@@ -872,7 +899,7 @@ static void* WINAPI expWaitForSingleObject(void* object, int duration)
if (duration == 0) {
if(ml->semaphore==0) ret = WAIT_FAILED;
else {
- ml->semaphore++;
+ ml->semaphore--;
ret = WAIT_OBJECT_0;
}
}
@@ -880,6 +907,25 @@ static void* WINAPI expWaitForSingleObject(void* object, int duration)
if (ml->semaphore==0)
pthread_cond_wait(ml->pc,ml->pm);
ml->semaphore--;
+ ret = WAIT_OBJECT_0;
+ }
+ break;
+ case 2: /* Mutex */
+ if (duration == 0) {
+ if(ml->lock_count > 0 && ml->owner != pthread_self()) ret = WAIT_FAILED;
+ else {
+ ml->lock_count++;
+ ml->owner = pthread_self();
+ ret = WAIT_OBJECT_0;
+ }
+ }
+ if (duration == -1) {
+ if (ml->lock_count > 0 && ml->owner != pthread_self()) {
+ pthread_cond_wait(ml->pc,ml->pm);
+ }
+ ml->lock_count++;
+ ml->owner = pthread_self();
+ ret = WAIT_OBJECT_0;
}
break;
}
@@ -917,31 +963,6 @@ static void WINAPI expExitThread(int retcode)
dbgprintf("ExitThread(%d)\n", retcode);
pthread_exit(&retcode);
}
-
-static HANDLE WINAPI expCreateMutexA(void *pSecAttr,
- char bInitialOwner, const char *name)
-{
- HANDLE mlist = (HANDLE)expCreateEventA(pSecAttr, 0, 0, name);
-
- if (name)
- dbgprintf("CreateMutexA(0x%x, %d, '%s') => 0x%x\n",
- pSecAttr, bInitialOwner, name, mlist);
- else
- dbgprintf("CreateMutexA(0x%x, %d, NULL) => 0x%x\n",
- pSecAttr, bInitialOwner, mlist);
-#ifndef CONFIG_QTX_CODECS
- /* 10l to QTX, if CreateMutex returns a real mutex, WaitForSingleObject
- waits for ever, else it works ;) */
- return mlist;
-#endif
-}
-
-static int WINAPI expReleaseMutex(HANDLE hMutex)
-{
- dbgprintf("ReleaseMutex(%x) => 1\n", hMutex);
- /* FIXME:XXX !! not yet implemented */
- return 1;
-}
#endif
static int pf_set = 0;
@@ -1801,6 +1822,7 @@ static HANDLE WINAPI expCreateSemaphoreA(char* v1, long init_count,
{
pthread_mutex_t *pm;
pthread_cond_t *pc;
+ HANDLE ret;
/*
mutex_list* pp;
printf("CreateSemaphoreA(%p = %s)\n", name, (name ? name : "<null>"));
@@ -1812,6 +1834,7 @@ static HANDLE WINAPI expCreateSemaphoreA(char* v1, long init_count,
}
printf("0\n");
*/
+ pthread_mutex_lock(&mlist_lock);
if(mlist!=NULL)
{
mutex_list* pp=mlist;
@@ -1822,7 +1845,9 @@ static HANDLE WINAPI expCreateSemaphoreA(char* v1, long init_count,
{
dbgprintf("CreateSemaphoreA(0x%x, init_count %d, max_count %d, name 0x%x='%s') => 0x%x\n",
v1, init_count, max_count, name, name, mlist);
- return (HANDLE)mlist;
+ ret = (HANDLE)mlist;
+ pthread_mutex_unlock(&mlist_lock);
+ return ret;
}
}while((pp=pp->prev) != NULL);
}
@@ -1861,7 +1886,9 @@ static HANDLE WINAPI expCreateSemaphoreA(char* v1, long init_count,
else
dbgprintf("CreateSemaphoreA(0x%x, init_count %d, max_count %d, name 0) => 0x%x\n",
v1, init_count, max_count, mlist);
- return (HANDLE)mlist;
+ ret = (HANDLE)mlist;
+ pthread_mutex_unlock(&mlist_lock);
+ return ret;
}
static long WINAPI expReleaseSemaphore(long hsem, long increment, long* prev_count)
@@ -1882,6 +1909,105 @@ static long WINAPI expReleaseSemaphore(long hsem, long increment, long* prev_cou
return 1;
}
+static HANDLE WINAPI expCreateMutexA(void *pSecAttr,
+ char bInitialOwner, const char *name)
+{
+ pthread_mutex_t *pm;
+ pthread_cond_t *pc;
+ HANDLE ret;
+ pthread_mutex_lock(&mlist_lock);
+ if(mlist!=NULL)
+ {
+ mutex_list* pp=mlist;
+ if(name!=NULL)
+ do
+ {
+ if((strcmp(pp->name, name)==0) && (pp->type==2))
+ {
+ dbgprintf("CreateMutexA(0x%x, %d, '%s') => 0x%x\n", pSecAttr, bInitialOwner, name, mlist);
+ ret = (HANDLE)mlist;
+ pthread_mutex_unlock(&mlist_lock);
+ return ret;
+ }
+ }while((pp=pp->prev) != NULL);
+ }
+ pm=mreq_private(sizeof(pthread_mutex_t), 0, AREATYPE_MUTEX);
+ pthread_mutex_init(pm, NULL);
+ pc=mreq_private(sizeof(pthread_cond_t), 0, AREATYPE_COND);
+ pthread_cond_init(pc, NULL);
+ if(mlist==NULL)
+ {
+ mlist=mreq_private(sizeof(mutex_list), 00, AREATYPE_EVENT);
+ mlist->next=mlist->prev=NULL;
+ }
+ else
+ {
+ mlist->next=mreq_private(sizeof(mutex_list), 00, AREATYPE_EVENT);
+ mlist->next->prev=mlist;
+ mlist->next->next=NULL;
+ mlist=mlist->next;
+ }
+ mlist->type=2; /* Type Mutex */
+ mlist->pm=pm;
+ mlist->pc=pc;
+ mlist->state=0;
+ mlist->reset=0;
+ mlist->semaphore=0;
+ if (bInitialOwner) {
+ mlist->owner = pthread_self();
+ mlist->lock_count = 1;
+ } else {
+ mlist->owner = (pthread_t)0;
+ mlist->lock_count = 0;
+ }
+ if(name!=NULL)
+ strncpy(mlist->name, name, 64);
+ else
+ mlist->name[0]=0;
+ if(pm==NULL)
+ dbgprintf("ERROR::: CreateMutexA failure\n");
+ if(name)
+ dbgprintf("CreateMutexA(0x%x, %d, '%s') => 0x%x\n",
+ pSecAttr, bInitialOwner, name, mlist);
+ else
+ dbgprintf("CreateMutexA(0x%x, %d, NULL) => 0x%x\n",
+ pSecAttr, bInitialOwner, mlist);
+ ret = (HANDLE)mlist;
+ pthread_mutex_unlock(&mlist_lock);
+ return ret;
+}
+
+static int WINAPI expReleaseMutex(HANDLE hMutex)
+{
+ mutex_list *ml = (mutex_list *)hMutex;
+
+ pthread_mutex_lock(ml->pm);
+ if (--ml->lock_count == 0) pthread_cond_signal(ml->pc);
+ pthread_mutex_unlock(ml->pm);
+ return 1;
+}
+
+static DWORD WINAPI expSignalObjectAndWait(HANDLE hObjectToSignal,
+ HANDLE hObjectToWaitOn,
+ DWORD dwMilliseconds,
+ WIN_BOOL bAlertable) {
+ mutex_list* mlist = (mutex_list*)hObjectToSignal;
+
+ switch (mlist->type) {
+ case 0: // Event
+ expSetEvent(mlist);
+ break;
+ case 1: // Semaphore
+ expReleaseSemaphore(mlist, 1, NULL);
+ break;
+ case 2: // Mutex
+ expReleaseMutex(mlist);
+ break;
+ default:
+ dbgprintf("Signalling unknown object type %d!\n", hObjectToSignal);
+ }
+ return expWaitForSingleObject(hObjectToWaitOn, dwMilliseconds);
+}
static long WINAPI expRegOpenKeyExA(long key, const char* subkey, long reserved, long access, int* newkey)
{
@@ -5002,6 +5128,7 @@ struct exports exp_kernel32[]=
FF(IsBadStringPtrA, -1)
FF(DisableThreadLibraryCalls, -1)
FF(CreateThread, -1)
+ FF(ResumeThread, -1)
FF(CreateEventA, -1)
FF(SetEvent, -1)
FF(ResetEvent, -1)
@@ -5009,8 +5136,6 @@ struct exports exp_kernel32[]=
#ifdef CONFIG_QTX_CODECS
FF(WaitForMultipleObjects, -1)
FF(ExitThread, -1)
- FF(CreateMutexA,-1)
- FF(ReleaseMutex,-1)
#endif
FF(GetSystemInfo, -1)
FF(GetVersion, 332)
@@ -5055,6 +5180,9 @@ struct exports exp_kernel32[]=
FF(GlobalFree, -1)
FF(LoadResource, -1)
FF(ReleaseSemaphore, -1)
+ FF(CreateMutexA, -1)
+ FF(ReleaseMutex, -1)
+ FF(SignalObjectAndWait, -1)
FF(FindResourceA, -1)
FF(LockResource, -1)
FF(FreeResource, -1)
@@ -5662,5 +5790,7 @@ void my_garbagecollection(void)
dbgprintf("Total Unfree %d bytes cnt %d [%p,%d]\n",unfree, unfreecnt, last_alloc, alccnt);
#endif
g_tls = NULL;
+ pthread_mutex_lock(&list_lock);
list = NULL;
+ pthread_mutex_unlock(&list_lock);
}