Mercurial > mplayer.hg
annotate loader/resource.c @ 24678:9aab9d7b51f0
Fix missing subtitles after seeking back
Subtitle packets that had been demuxed but whose start time had not
yet been reached were left in the demuxer stream after seeking.
When using the default (non-libass) subtitle rendering this could
block subtitles from appearing as long as the playback position stayed
below the original one before seek. External subtitle files were not
affected.
Fixed by making seek code free all packets from the subtitle stream.
author | uau |
---|---|
date | Thu, 04 Oct 2007 02:35:34 +0000 |
parents | 3a8d72016ed7 |
children | 2c8cdb9123b8 |
rev | line source |
---|---|
1 | 1 /* |
2 * Resources | |
3 * | |
4 * Copyright 1993 Robert J. Amstadt | |
5 * Copyright 1995 Alexandre Julliard | |
15166
f5537cc95b02
Mark modified imported files as such to comply with GPL ¡ø2a.
diego
parents:
11000
diff
changeset
|
6 * |
18783 | 7 * Modified for use with MPlayer, detailed changelog at |
8 * http://svn.mplayerhq.hu/mplayer/trunk/ | |
15166
f5537cc95b02
Mark modified imported files as such to comply with GPL ¡ø2a.
diego
parents:
11000
diff
changeset
|
9 * $Id$ |
f5537cc95b02
Mark modified imported files as such to comply with GPL ¡ø2a.
diego
parents:
11000
diff
changeset
|
10 * |
1 | 11 */ |
7386 | 12 #include "config.h" |
21261
a2e02e6b6379
Rename config.h --> debug.h and include config.h explicitly.
diego
parents:
18783
diff
changeset
|
13 #include "debug.h" |
1 | 14 |
15 #include <assert.h> | |
1307
d8c1b0b38edc
Add prototypes to wine/loader stuff, so that we can catch __stdcall function
jkeil
parents:
1
diff
changeset
|
16 #include <stdio.h> |
1 | 17 #include <stdlib.h> |
18 #include <string.h> | |
19 #include <sys/types.h> | |
20 #include <sys/stat.h> | |
21 #include <fcntl.h> | |
22 #include <unistd.h> | |
7386 | 23 |
24 #include "wine/winbase.h" | |
25 #include "wine/windef.h" | |
26 #include "wine/winuser.h" | |
27 #include "wine/heap.h" | |
28 #include "wine/module.h" | |
29 #include "wine/debugtools.h" | |
30 #include "wine/winerror.h" | |
31 #include "loader.h" | |
1307
d8c1b0b38edc
Add prototypes to wine/loader stuff, so that we can catch __stdcall function
jkeil
parents:
1
diff
changeset
|
32 |
1 | 33 #define CP_ACP 0 |
34 | |
35 WORD WINE_LanguageId=0x409;//english | |
36 | |
37 #define HRSRC_MAP_BLOCKSIZE 16 | |
38 | |
39 typedef struct _HRSRC_ELEM | |
40 { | |
41 HANDLE hRsrc; | |
42 WORD type; | |
43 } HRSRC_ELEM; | |
44 | |
45 typedef struct _HRSRC_MAP | |
46 { | |
47 int nAlloc; | |
48 int nUsed; | |
49 HRSRC_ELEM *elem; | |
50 } HRSRC_MAP; | |
51 | |
52 static HRSRC RES_FindResource2( HMODULE hModule, LPCSTR type, | |
53 LPCSTR name, WORD lang, int unicode) | |
54 { | |
55 HRSRC hRsrc = 0; | |
56 LPWSTR typeStr, nameStr; | |
57 WINE_MODREF *wm = MODULE32_LookupHMODULE( hModule ); | |
58 | |
59 if(!wm) | |
60 return 0; | |
61 /* 32-bit PE module */ | |
62 | |
63 | |
64 if ( HIWORD( type ) && (!unicode)) | |
65 typeStr = HEAP_strdupAtoW( GetProcessHeap(), 0, type ); | |
66 else | |
67 typeStr = (LPWSTR)type; | |
68 if ( HIWORD( name ) && (!unicode)) | |
69 nameStr = HEAP_strdupAtoW( GetProcessHeap(), 0, name ); | |
70 else | |
71 nameStr = (LPWSTR)name; | |
72 | |
73 hRsrc = PE_FindResourceExW( wm, nameStr, typeStr, lang ); | |
74 | |
75 if ( HIWORD( type ) && (!unicode)) | |
76 HeapFree( GetProcessHeap(), 0, typeStr ); | |
77 if ( HIWORD( name ) && (!unicode)) | |
78 HeapFree( GetProcessHeap(), 0, nameStr ); | |
79 | |
80 return hRsrc; | |
81 } | |
82 | |
83 /********************************************************************** | |
84 * RES_FindResource | |
85 */ | |
86 | |
87 static HRSRC RES_FindResource( HMODULE hModule, LPCSTR type, | |
88 LPCSTR name, WORD lang, int unicode ) | |
89 { | |
90 HRSRC hRsrc; | |
91 // __TRY | |
92 // { | |
93 hRsrc = RES_FindResource2(hModule, type, name, lang, unicode); | |
94 // } | |
95 // __EXCEPT(page_fault) | |
96 // { | |
97 // WARN("page fault\n"); | |
98 // SetLastError(ERROR_INVALID_PARAMETER); | |
99 // return 0; | |
100 // } | |
101 // __ENDTRY | |
102 return hRsrc; | |
103 } | |
104 | |
105 /********************************************************************** | |
106 * RES_SizeofResource | |
107 */ | |
108 static DWORD RES_SizeofResource( HMODULE hModule, HRSRC hRsrc) | |
109 { | |
110 DWORD size = 0; | |
24386 | 111 // HRSRC hRsrc32; |
1 | 112 |
113 // HMODULE16 hMod16 = MapHModuleLS( hModule ); | |
114 // NE_MODULE *pModule = NE_GetPtr( hMod16 ); | |
115 // WINE_MODREF *wm = pModule && pModule->module32? | |
116 // MODULE32_LookupHMODULE( pModule->module32 ) : NULL; | |
117 WINE_MODREF *wm = MODULE32_LookupHMODULE( hModule ); | |
118 | |
119 if ( !hModule || !hRsrc ) return 0; | |
120 | |
121 /* 32-bit PE module */ | |
122 /* If we got a 16-bit hRsrc, convert it */ | |
123 // hRsrc32 = HIWORD(hRsrc)? hRsrc : MapHRsrc16To32( pModule, hRsrc ); | |
124 if(!HIWORD(hRsrc)) | |
125 { | |
126 printf("16-bit hRsrcs not supported\n"); | |
127 return 0; | |
128 } | |
129 size = PE_SizeofResource( hModule, hRsrc ); | |
130 return size; | |
131 } | |
132 | |
133 /********************************************************************** | |
134 * RES_AccessResource | |
135 */ | |
136 static HFILE RES_AccessResource( HMODULE hModule, HRSRC hRsrc ) | |
137 { | |
138 HFILE hFile = HFILE_ERROR; | |
139 | |
140 WINE_MODREF *wm = MODULE32_LookupHMODULE( hModule ); | |
141 | |
142 if ( !hModule || !hRsrc ) return HFILE_ERROR; | |
143 | |
144 /* 32-bit PE module */ | |
145 FIXME("32-bit modules not yet supported.\n" ); | |
146 hFile = HFILE_ERROR; | |
147 | |
148 return hFile; | |
149 } | |
150 | |
151 /********************************************************************** | |
152 * RES_LoadResource | |
153 */ | |
154 static HGLOBAL RES_LoadResource( HMODULE hModule, HRSRC hRsrc) | |
155 { | |
156 HGLOBAL hMem = 0; | |
24386 | 157 // HRSRC hRsrc32; |
1 | 158 WINE_MODREF *wm = MODULE32_LookupHMODULE( hModule ); |
159 | |
160 | |
161 if ( !hModule || !hRsrc ) return 0; | |
162 | |
163 /* 32-bit PE module */ | |
164 | |
165 /* If we got a 16-bit hRsrc, convert it */ | |
166 // hRsrc32 = HIWORD(hRsrc)? hRsrc : MapHRsrc16To32( pModule, hRsrc ); | |
167 if(!HIWORD(hRsrc)) | |
168 { | |
169 printf("16-bit hRsrcs not supported\n"); | |
170 return 0; | |
171 } | |
172 hMem = PE_LoadResource( wm, hRsrc ); | |
173 | |
174 return hMem; | |
175 } | |
176 | |
177 /********************************************************************** | |
178 * RES_LockResource | |
179 */ | |
180 static LPVOID RES_LockResource( HGLOBAL handle ) | |
181 { | |
182 LPVOID bits = NULL; | |
183 | |
184 TRACE("(%08x, %s)\n", handle, "PE" ); | |
185 | |
186 bits = (LPVOID)handle; | |
187 | |
188 return bits; | |
189 } | |
190 | |
191 /********************************************************************** | |
192 * RES_FreeResource | |
193 */ | |
194 static WIN_BOOL RES_FreeResource( HGLOBAL handle ) | |
195 { | |
196 HGLOBAL retv = handle; | |
197 return (WIN_BOOL)retv; | |
198 } | |
199 | |
200 /********************************************************************** | |
201 * FindResourceA (KERNEL32.128) | |
202 */ | |
203 HANDLE WINAPI FindResourceA( HMODULE hModule, LPCSTR name, LPCSTR type ) | |
204 { | |
205 return RES_FindResource( hModule, type, name, | |
206 WINE_LanguageId, 0); | |
207 } | |
208 HANDLE WINAPI FindResourceW( HMODULE hModule, LPCWSTR name, LPCWSTR type ) | |
209 { | |
210 return RES_FindResource( hModule, (LPCSTR)type, (LPCSTR)name, | |
211 WINE_LanguageId, 1); | |
212 } | |
213 | |
214 /********************************************************************** | |
215 * FindResourceExA (KERNEL32.129) | |
216 */ | |
217 HANDLE WINAPI FindResourceExA( HMODULE hModule, | |
218 LPCSTR type, LPCSTR name, WORD lang ) | |
219 { | |
220 return RES_FindResource( hModule, type, name, | |
221 lang, 0 ); | |
222 } | |
223 | |
224 HANDLE WINAPI FindResourceExW( HMODULE hModule, | |
225 LPCWSTR type, LPCWSTR name, WORD lang ) | |
226 { | |
227 return RES_FindResource( hModule, (LPCSTR)type, (LPCSTR)name, | |
228 lang, 1 ); | |
229 } | |
230 | |
231 | |
232 | |
233 /********************************************************************** | |
234 * LockResource (KERNEL32.384) | |
235 */ | |
236 LPVOID WINAPI LockResource( HGLOBAL handle ) | |
237 { | |
238 return RES_LockResource( handle ); | |
239 } | |
240 | |
241 | |
242 /********************************************************************** | |
243 * FreeResource (KERNEL32.145) | |
244 */ | |
245 WIN_BOOL WINAPI FreeResource( HGLOBAL handle ) | |
246 { | |
247 return RES_FreeResource( handle ); | |
248 } | |
249 | |
250 | |
251 /********************************************************************** | |
252 * AccessResource (KERNEL32.64) | |
253 */ | |
254 INT WINAPI AccessResource( HMODULE hModule, HRSRC hRsrc ) | |
255 { | |
256 return RES_AccessResource( hModule, hRsrc ); | |
257 } | |
258 /********************************************************************** | |
259 * SizeofResource (KERNEL32.522) | |
260 */ | |
261 DWORD WINAPI SizeofResource( HINSTANCE hModule, HRSRC hRsrc ) | |
262 { | |
263 return RES_SizeofResource( hModule, hRsrc ); | |
264 } | |
265 | |
266 | |
267 INT WINAPI LoadStringW( HINSTANCE instance, UINT resource_id, | |
268 LPWSTR buffer, INT buflen ); | |
269 | |
270 /********************************************************************** | |
271 * LoadStringA (USER32.375) | |
272 */ | |
273 INT WINAPI LoadStringA( HINSTANCE instance, UINT resource_id, | |
274 LPSTR buffer, INT buflen ) | |
275 { | |
276 INT retval; | |
277 INT wbuflen; | |
278 INT abuflen; | |
279 LPWSTR wbuf = NULL; | |
280 LPSTR abuf = NULL; | |
281 | |
282 if ( buffer != NULL && buflen > 0 ) | |
283 *buffer = 0; | |
284 | |
285 wbuflen = LoadStringW(instance,resource_id,NULL,0); | |
286 if ( !wbuflen ) | |
287 return 0; | |
288 wbuflen ++; | |
289 | |
290 retval = 0; | |
7386 | 291 wbuf = (LPWSTR) HeapAlloc( GetProcessHeap(), 0, wbuflen * sizeof(WCHAR) ); |
1 | 292 wbuflen = LoadStringW(instance,resource_id,wbuf,wbuflen); |
293 if ( wbuflen > 0 ) | |
294 { | |
295 abuflen = WideCharToMultiByte(CP_ACP,0,wbuf,wbuflen,NULL,0,NULL,NULL); | |
296 if ( abuflen > 0 ) | |
297 { | |
298 if ( buffer == NULL || buflen == 0 ) | |
299 retval = abuflen; | |
300 else | |
301 { | |
7386 | 302 abuf = (LPSTR) HeapAlloc( GetProcessHeap(), 0, abuflen * sizeof(CHAR) ); |
1 | 303 abuflen = WideCharToMultiByte(CP_ACP,0,wbuf,wbuflen,abuf,abuflen,NULL,NULL); |
304 if ( abuflen > 0 ) | |
305 { | |
306 abuflen = min(abuflen,buflen - 1); | |
307 memcpy( buffer, abuf, abuflen ); | |
308 buffer[abuflen] = 0; | |
309 retval = abuflen; | |
310 } | |
311 HeapFree( GetProcessHeap(), 0, abuf ); | |
312 } | |
313 } | |
314 } | |
315 HeapFree( GetProcessHeap(), 0, wbuf ); | |
316 | |
317 return retval; | |
318 } | |
319 | |
320 /********************************************************************** | |
321 * LoadStringW (USER32.376) | |
322 */ | |
323 INT WINAPI LoadStringW( HINSTANCE instance, UINT resource_id, | |
324 LPWSTR buffer, INT buflen ) | |
325 { | |
326 HGLOBAL hmem; | |
327 HRSRC hrsrc; | |
328 WCHAR *p; | |
329 int string_num; | |
330 int i; | |
331 | |
332 if (HIWORD(resource_id)==0xFFFF) /* netscape 3 passes this */ | |
333 resource_id = (UINT)(-((INT)resource_id)); | |
334 TRACE("instance = %04x, id = %04x, buffer = %08x, " | |
335 "length = %d\n", instance, (int)resource_id, (int) buffer, buflen); | |
336 | |
337 /* Use bits 4 - 19 (incremented by 1) as resourceid, mask out | |
338 * 20 - 31. */ | |
339 hrsrc = FindResourceW( instance, (LPCWSTR)(((resource_id>>4)&0xffff)+1), | |
340 RT_STRINGW ); | |
341 if (!hrsrc) return 0; | |
342 hmem = LoadResource( instance, hrsrc ); | |
343 if (!hmem) return 0; | |
344 | |
7386 | 345 p = (WCHAR*) LockResource(hmem); |
1 | 346 string_num = resource_id & 0x000f; |
347 for (i = 0; i < string_num; i++) | |
348 p += *p + 1; | |
349 | |
350 TRACE("strlen = %d\n", (int)*p ); | |
351 | |
352 if (buffer == NULL) return *p; | |
353 i = min(buflen - 1, *p); | |
354 if (i > 0) { | |
355 memcpy(buffer, p + 1, i * sizeof (WCHAR)); | |
356 buffer[i] = (WCHAR) 0; | |
357 } else { | |
358 if (buflen > 1) { | |
359 buffer[0] = (WCHAR) 0; | |
360 return 0; | |
361 } | |
362 #if 0 | |
11000 | 363 WARN("Don't know why caller give buflen=%d *p=%d trying to obtain string '%s'\n", buflen, *p, p + 1); |
1 | 364 #endif |
365 } | |
366 | |
367 TRACE("String loaded !\n"); | |
368 return i; | |
369 } | |
370 | |
371 /* Messages...used by FormatMessage32* (KERNEL32.something) | |
372 * | |
373 * They can be specified either directly or using a message ID and | |
374 * loading them from the resource. | |
375 * | |
376 * The resourcedata has following format: | |
377 * start: | |
378 * 0: DWORD nrofentries | |
379 * nrofentries * subentry: | |
380 * 0: DWORD firstentry | |
381 * 4: DWORD lastentry | |
382 * 8: DWORD offset from start to the stringentries | |
383 * | |
384 * (lastentry-firstentry) * stringentry: | |
385 * 0: WORD len (0 marks end) | |
386 * 2: WORD flags | |
387 * 4: CHAR[len-4] | |
388 * (stringentry i of a subentry refers to the ID 'firstentry+i') | |
389 * | |
390 * Yes, ANSI strings in win32 resources. Go figure. | |
391 */ | |
392 | |
393 /********************************************************************** | |
394 * LoadMessageA (internal) | |
395 */ | |
396 INT WINAPI LoadMessageA( HMODULE instance, UINT id, WORD lang, | |
397 LPSTR buffer, INT buflen ) | |
398 { | |
399 HGLOBAL hmem; | |
400 HRSRC hrsrc; | |
401 PMESSAGE_RESOURCE_DATA mrd; | |
402 PMESSAGE_RESOURCE_BLOCK mrb; | |
403 PMESSAGE_RESOURCE_ENTRY mre; | |
404 int i,slen; | |
405 | |
406 TRACE("instance = %08lx, id = %08lx, buffer = %p, length = %ld\n", (DWORD)instance, (DWORD)id, buffer, (DWORD)buflen); | |
407 | |
408 /*FIXME: I am not sure about the '1' ... But I've only seen those entries*/ | |
409 hrsrc = FindResourceExW(instance,RT_MESSAGELISTW,(LPWSTR)1,lang); | |
410 if (!hrsrc) return 0; | |
411 hmem = LoadResource( instance, hrsrc ); | |
412 if (!hmem) return 0; | |
413 | |
414 mrd = (PMESSAGE_RESOURCE_DATA)LockResource(hmem); | |
415 mre = NULL; | |
416 mrb = &(mrd->Blocks[0]); | |
417 for (i=mrd->NumberOfBlocks;i--;) { | |
418 if ((id>=mrb->LowId) && (id<=mrb->HighId)) { | |
419 mre = (PMESSAGE_RESOURCE_ENTRY)(((char*)mrd)+mrb->OffsetToEntries); | |
420 id -= mrb->LowId; | |
421 break; | |
422 } | |
423 mrb++; | |
424 } | |
425 if (!mre) | |
426 return 0; | |
427 for (i=id;i--;) { | |
428 if (!mre->Length) | |
429 return 0; | |
430 mre = (PMESSAGE_RESOURCE_ENTRY)(((char*)mre)+(mre->Length)); | |
431 } | |
432 slen=mre->Length; | |
433 TRACE(" - strlen=%d\n",slen); | |
434 i = min(buflen - 1, slen); | |
435 if (buffer == NULL) | |
436 return slen; | |
437 if (i>0) { | |
438 lstrcpynA(buffer,(char*)mre->Text,i); | |
439 buffer[i]=0; | |
440 } else { | |
441 if (buflen>1) { | |
442 buffer[0]=0; | |
443 return 0; | |
444 } | |
445 } | |
446 if (buffer) | |
447 TRACE("'%s' copied !\n", buffer); | |
448 return i; | |
449 } | |
450 | |
451 | |
452 | |
453 /********************************************************************** | |
454 * EnumResourceTypesA (KERNEL32.90) | |
455 */ | |
456 WIN_BOOL WINAPI EnumResourceTypesA( HMODULE hmodule,ENUMRESTYPEPROCA lpfun, | |
457 LONG lParam) | |
458 { | |
459 /* FIXME: move WINE_MODREF stuff here */ | |
460 return PE_EnumResourceTypesA(hmodule,lpfun,lParam); | |
461 } | |
462 | |
463 /********************************************************************** | |
464 * EnumResourceNamesA (KERNEL32.88) | |
465 */ | |
466 WIN_BOOL WINAPI EnumResourceNamesA( HMODULE hmodule, LPCSTR type, | |
467 ENUMRESNAMEPROCA lpfun, LONG lParam ) | |
468 { | |
469 /* FIXME: move WINE_MODREF stuff here */ | |
470 return PE_EnumResourceNamesA(hmodule,type,lpfun,lParam); | |
471 } | |
472 /********************************************************************** | |
473 * EnumResourceLanguagesA (KERNEL32.86) | |
474 */ | |
475 WIN_BOOL WINAPI EnumResourceLanguagesA( HMODULE hmodule, LPCSTR type, | |
476 LPCSTR name, ENUMRESLANGPROCA lpfun, | |
477 LONG lParam) | |
478 { | |
479 /* FIXME: move WINE_MODREF stuff here */ | |
480 return PE_EnumResourceLanguagesA(hmodule,type,name,lpfun,lParam); | |
481 } | |
482 /********************************************************************** | |
483 * LoadResource (KERNEL32.370) | |
484 */ | |
485 HGLOBAL WINAPI LoadResource( HINSTANCE hModule, HRSRC hRsrc ) | |
486 { | |
487 return RES_LoadResource( hModule, hRsrc); | |
488 } |