Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*************************************************************************
3 : *
4 : * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 : *
6 : * Copyright 2000, 2010 Oracle and/or its affiliates.
7 : *
8 : * OpenOffice.org - a multi-platform office productivity suite
9 : *
10 : * This file is part of OpenOffice.org.
11 : *
12 : * OpenOffice.org is free software: you can redistribute it and/or modify
13 : * it under the terms of the GNU Lesser General Public License version 3
14 : * only, as published by the Free Software Foundation.
15 : *
16 : * OpenOffice.org is distributed in the hope that it will be useful,
17 : * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 : * GNU Lesser General Public License version 3 for more details
20 : * (a copy is included in the LICENSE file that accompanied this code).
21 : *
22 : * You should have received a copy of the GNU Lesser General Public License
23 : * version 3 along with OpenOffice.org. If not, see
24 : * <http://www.openoffice.org/license.html>
25 : * for a copy of the LGPLv3 License.
26 : *
27 : ************************************************************************/
28 :
29 :
30 : #ifdef AIX
31 : #define _LINUX_SOURCE_COMPAT
32 : #include <sys/timer.h>
33 : #undef _LINUX_SOURCE_COMPAT
34 : #endif
35 :
36 : #ifdef WNT
37 : #include <prewin.h>
38 : #include <postwin.h>
39 : #undef OPTIONAL
40 : #endif
41 :
42 : #include <cstdarg>
43 : #include <list>
44 :
45 : #include <plugin/impl.hxx>
46 : #include <vcl/svapp.hxx>
47 :
48 : #if OSL_DEBUG_LEVEL > 1
49 : #include <osl/thread.h>
50 : #include <stdio.h>
51 : static FILE * s_file = 0;
52 : void TRACE( char const * s )
53 : {
54 : if (! s_file)
55 : s_file = stderr;
56 : if (s_file)
57 : {
58 : oslThreadIdentifier t = osl_getThreadIdentifier(0);
59 : fprintf( s_file, "log [t_id=%" SAL_PRIuUINT32 "]: %s\n", t, s );
60 : fflush( s_file );
61 : }
62 : }
63 : void TRACEN( char const * s, long n )
64 : {
65 : if (! s_file)
66 : s_file = stderr;
67 : if (s_file)
68 : {
69 : oslThreadIdentifier t = osl_getThreadIdentifier(0);
70 : fprintf( s_file, "log [t_id=%" SAL_PRIuUINT32 "]: %s%ld\n", t, s, n );
71 : fflush( s_file );
72 : }
73 : }
74 : void TRACES( char const* s, char const* s2 )
75 : {
76 : if (! s_file)
77 : s_file = stderr;
78 : if (s_file)
79 : {
80 : oslThreadIdentifier t = osl_getThreadIdentifier(0);
81 : fprintf( s_file, "log [t_id=%" SAL_PRIuUINT32 "]: %s %s\n", t, s, s2 );
82 : fflush( s_file );
83 : }
84 : }
85 : #else
86 : #define TRACE(x)
87 : #define TRACEN(x,n)
88 : #define TRACES(x,s)
89 : #endif
90 :
91 : using namespace com::sun::star::lang;
92 :
93 :
94 : // Move deprecated functions which no longer appear in npapi.h before
95 : // their use to avoid errors that they're undeclared at point of use
96 : extern "C"
97 : {
98 0 : const JRIEnvInterface** SAL_CALL NP_LOADDS NPN_GetJavaEnv()
99 : {
100 : TRACE( "NPN_GetJavaEnv" );
101 : // no java in this program
102 0 : return NULL;
103 : }
104 :
105 0 : jref SAL_CALL NP_LOADDS NPN_GetJavaPeer( NPP /*instance*/ )
106 : {
107 : TRACE( "NPN_GetJavaPeer" );
108 0 : return NULL;
109 : }
110 : }
111 :
112 : NPNetscapeFuncs aNPNFuncs =
113 : {
114 : sizeof( NPNetscapeFuncs ),
115 : (NP_VERSION_MAJOR << 8) | NP_VERSION_MINOR,
116 : NPN_GetURL,
117 : NPN_PostURL,
118 : NPN_RequestRead,
119 : NPN_NewStream,
120 : NPN_Write,
121 : NPN_DestroyStream,
122 : NPN_Status,
123 : NPN_UserAgent,
124 : NPN_MemAlloc,
125 : NPN_MemFree,
126 : NPN_MemFlush,
127 : NPN_ReloadPlugins,
128 : NPN_GetJavaEnv,
129 : NPN_GetJavaPeer,
130 : NPN_GetURLNotify,
131 : NPN_PostURLNotify,
132 : NPN_GetValue,
133 : NPN_SetValue,
134 : NPN_InvalidateRect,
135 : NPN_InvalidateRegion,
136 : NPN_ForceRedraw
137 : };
138 :
139 0 : static OString normalizeURL( XPlugin_Impl* plugin, const OString& url )
140 : {
141 0 : OString aLoadURL;
142 0 : if( url.indexOf( ':' ) == -1 )
143 : {
144 0 : aLoadURL = OUStringToOString( plugin->getCreationURL(), plugin->getTextEncoding() );
145 : int nPos;
146 0 : if( ( nPos = aLoadURL.indexOf( "://" ) ) != -1 )
147 : {
148 0 : if( !url.isEmpty() && (url.getStr()[ 0 ] == '/' || url.indexOf( '/' ) != -1) )
149 : {
150 : // this means same server but new path
151 0 : nPos = aLoadURL.indexOf( '/', nPos+3 );
152 :
153 0 : if( nPos != -1 )
154 0 : aLoadURL = aLoadURL.copy( 0, url.getStr()[0] == '/' ? nPos : nPos+1 );
155 : }
156 : else
157 : {
158 : // same server but new file
159 0 : nPos = aLoadURL.lastIndexOf( '/' );
160 0 : aLoadURL = aLoadURL.copy( 0, nPos+1 );
161 : }
162 0 : aLoadURL += url;
163 : }
164 : else
165 0 : aLoadURL = url;
166 : }
167 0 : else if( url.indexOf( ":/" ) != -1 )
168 0 : aLoadURL = url;
169 :
170 0 : return aLoadURL;
171 : }
172 :
173 0 : struct AsynchronousGetURL
174 : {
175 : OUString aUrl;
176 : OUString aTarget;
177 : Reference< XEventListener > xListener;
178 :
179 : DECL_LINK( getURL, XPlugin_Impl* );
180 : };
181 :
182 0 : IMPL_LINK( AsynchronousGetURL, getURL, XPlugin_Impl*, pImpl )
183 : {
184 : try
185 : {
186 0 : pImpl->enterPluginCallback();
187 0 : if( xListener.is() )
188 0 : pImpl->getPluginContext()->
189 : getURLNotify( pImpl,
190 : aUrl,
191 : aTarget,
192 0 : xListener );
193 : else
194 0 : pImpl->getPluginContext()->
195 : getURL( pImpl,
196 : aUrl,
197 0 : aTarget );
198 : }
199 0 : catch(const ::com::sun::star::plugin::PluginException&)
200 : {
201 : }
202 0 : pImpl->leavePluginCallback();
203 0 : delete this;
204 0 : return 0;
205 : }
206 :
207 :
208 : extern "C" {
209 :
210 0 : void* SAL_CALL NP_LOADDS NPN_MemAlloc( uint32_t nBytes )
211 : {
212 : TRACE( "NPN_MemAlloc" );
213 0 : void* pMem = malloc( nBytes );
214 0 : return pMem;
215 : }
216 :
217 0 : void SAL_CALL NP_LOADDS NPN_MemFree( void* pMem )
218 : {
219 : TRACE( "NPN_MemFree" );
220 0 : free( pMem );
221 0 : }
222 :
223 0 : uint32_t SAL_CALL NP_LOADDS NPN_MemFlush( uint32_t /*nSize*/ )
224 : {
225 : TRACE( "NPN_MemFlush" );
226 0 : return 0;
227 : }
228 :
229 0 : NPError SAL_CALL NP_LOADDS NPN_DestroyStream( NPP instance, NPStream* stream, NPError /*reason*/ )
230 : {
231 : TRACE( "NPN_DestroyStream" );
232 0 : XPlugin_Impl* pImpl = XPluginManager_Impl::getXPluginFromNPP( instance );
233 0 : if( ! pImpl )
234 0 : return NPERR_INVALID_INSTANCE_ERROR;
235 :
236 0 : PluginStream* pStream = pImpl->getStreamFromNPStream( stream );
237 0 : if( pStream )
238 : {
239 0 : if( pStream->getStreamType() == InputStream )
240 0 : static_cast<PluginInputStream*>(pStream)->releaseSelf();
241 : else
242 0 : delete pStream;
243 : }
244 :
245 0 : return NPERR_NO_ERROR;
246 : }
247 :
248 0 : NPError SAL_CALL NP_LOADDS NPN_GetURL( NPP instance, const char* url, const char* window )
249 : {
250 : TRACES( "NPN_GetURL", url );
251 0 : XPlugin_Impl* pImpl = XPluginManager_Impl::getXPluginFromNPP( instance );
252 0 : if( ! pImpl )
253 0 : return NPERR_INVALID_INSTANCE_ERROR;
254 :
255 0 : AsynchronousGetURL* pAsync = new AsynchronousGetURL();
256 :
257 0 : OString aLoadURL = normalizeURL( pImpl, url );
258 : TRACES( "NPN_GetURL", aLoadURL.getStr() );
259 0 : pAsync->aUrl = OStringToOUString( aLoadURL, pImpl->getTextEncoding() );
260 0 : pAsync->aTarget = OStringToOUString( window, pImpl->getTextEncoding() );
261 0 : pImpl->setLastGetUrl( aLoadURL );
262 0 : Application::PostUserEvent( LINK( pAsync, AsynchronousGetURL, getURL ), pImpl );
263 0 : return NPERR_NO_ERROR;
264 : }
265 :
266 0 : NPError SAL_CALL NP_LOADDS NPN_GetURLNotify( NPP instance, const char* url, const char* target,
267 : void* notifyData )
268 : {
269 : TRACES( "NPN_GetURLNotify", url );
270 0 : XPlugin_Impl* pImpl = XPluginManager_Impl::getXPluginFromNPP( instance );
271 0 : if( ! pImpl )
272 0 : return NPERR_INVALID_INSTANCE_ERROR;
273 :
274 0 : OString aLoadURL = normalizeURL( pImpl, url );
275 0 : if( aLoadURL.isEmpty() )
276 0 : return NPERR_INVALID_URL;
277 :
278 0 : AsynchronousGetURL* pAsync = new AsynchronousGetURL();
279 : PluginEventListener* pListener =
280 0 : new PluginEventListener( pImpl, url, aLoadURL.getStr(), notifyData );
281 0 : if( ! target || ! *target )
282 : {
283 : // stream will be fed back to plugin,
284 : // notify immediately after destruction of stream
285 0 : pImpl->addPluginEventListener( pListener );
286 0 : pListener = NULL;
287 : }
288 0 : pAsync->aUrl = OStringToOUString( aLoadURL, pImpl->getTextEncoding() );
289 0 : pAsync->aTarget = OStringToOUString( target, pImpl->getTextEncoding() );
290 0 : pAsync->xListener = pListener;
291 0 : pImpl->setLastGetUrl( aLoadURL );
292 0 : Application::PostUserEvent( LINK( pAsync, AsynchronousGetURL, getURL ), pImpl );
293 :
294 0 : return NPERR_NO_ERROR;
295 : }
296 :
297 0 : NPError SAL_CALL NP_LOADDS NPN_NewStream( NPP instance, NPMIMEType type, const char* target,
298 : NPStream** stream )
299 : // stream is a return value
300 : {
301 : TRACE( "NPN_NewStream" );
302 0 : XPlugin_Impl* pImpl = XPluginManager_Impl::getXPluginFromNPP( instance );
303 0 : if( ! pImpl )
304 0 : return NPERR_INVALID_INSTANCE_ERROR;
305 :
306 : PluginOutputStream* pStream = new PluginOutputStream( pImpl,
307 0 : "", 0, 0 );
308 0 : *stream = pStream->getStream();
309 :
310 : try
311 : {
312 0 : pImpl->enterPluginCallback();
313 0 : pImpl->getPluginContext()->
314 : newStream(
315 : pImpl,
316 0 : OStringToOUString( type, pImpl->getTextEncoding () ),
317 0 : OStringToOUString( target, pImpl->getTextEncoding() ),
318 0 : ::com::sun::star::uno::Reference< ::com::sun::star::io::XActiveDataSource > ( pStream->getOutputStream(), UNO_QUERY )
319 0 : );
320 0 : pImpl->leavePluginCallback();
321 : }
322 0 : catch( const ::com::sun::star::plugin::PluginException& e )
323 : {
324 0 : pImpl->leavePluginCallback();
325 0 : return e.ErrorCode;
326 : }
327 :
328 0 : return NPERR_NO_ERROR;
329 : }
330 :
331 0 : NPError SAL_CALL NP_LOADDS NPN_PostURLNotify( NPP instance, const char* url, const char* target, uint32_t len, const char* buf, NPBool file, void* notifyData )
332 : {
333 : TRACE( "NPN_PostURLNotify" );
334 0 : XPlugin_Impl* pImpl = XPluginManager_Impl::getXPluginFromNPP( instance );
335 0 : if( ! pImpl )
336 0 : return NPERR_INVALID_INSTANCE_ERROR;
337 :
338 0 : ::com::sun::star::uno::Sequence<sal_Int8> Bytes( (sal_Int8*)buf, len );
339 :
340 0 : OString aPostURL = normalizeURL( pImpl, url );
341 : PluginEventListener* pListener =
342 0 : new PluginEventListener( pImpl, url, aPostURL.getStr(), notifyData );
343 :
344 0 : if( ! target || ! *target )
345 : {
346 : // stream will be fed back to plugin,
347 : // notify immediately after destruction of stream
348 0 : pImpl->addPluginEventListener( pListener );
349 0 : pListener = NULL;
350 : }
351 :
352 : try
353 : {
354 0 : pImpl->enterPluginCallback();
355 0 : pImpl->getPluginContext()->
356 : postURLNotify( pImpl,
357 0 : OStringToOUString( aPostURL, pImpl->getTextEncoding() ),
358 0 : OStringToOUString( target, pImpl->getTextEncoding() ),
359 : Bytes,
360 : file,
361 0 : ::com::sun::star::uno::Reference< ::com::sun::star::lang::XEventListener > ( pListener ) );
362 0 : pImpl->leavePluginCallback();
363 : }
364 0 : catch( const ::com::sun::star::plugin::PluginException& e )
365 : {
366 0 : pImpl->leavePluginCallback();
367 0 : return e.ErrorCode;
368 : }
369 :
370 0 : return NPERR_NO_ERROR;
371 : }
372 :
373 0 : NPError SAL_CALL NP_LOADDS NPN_PostURL( NPP instance, const char* url, const char* window, uint32_t len, const char* buf, NPBool file )
374 : {
375 : TRACE( "NPN_PostURL" );
376 0 : XPlugin_Impl* pImpl = XPluginManager_Impl::getXPluginFromNPP( instance );
377 0 : if( ! pImpl )
378 0 : return NPERR_INVALID_INSTANCE_ERROR;
379 :
380 0 : ::com::sun::star::uno::Sequence<sal_Int8> Bytes( (sal_Int8*)buf, len );
381 0 : OString aPostURL = normalizeURL( pImpl, url );
382 : try
383 : {
384 0 : pImpl->enterPluginCallback();
385 0 : pImpl->getPluginContext()->
386 : postURL( pImpl,
387 0 : OStringToOUString( aPostURL, pImpl->getTextEncoding() ),
388 0 : OStringToOUString( window, pImpl->getTextEncoding () ),
389 : Bytes,
390 0 : file );
391 0 : pImpl->leavePluginCallback();
392 : }
393 0 : catch( const ::com::sun::star::plugin::PluginException& e )
394 : {
395 0 : pImpl->leavePluginCallback();
396 0 : return e.ErrorCode;
397 : }
398 :
399 0 : return NPERR_NO_ERROR;
400 : }
401 :
402 0 : NPError SAL_CALL NP_LOADDS NPN_RequestRead( NPStream* stream, NPByteRange* rangeList )
403 : {
404 : TRACE( "NPN_RequestRead" );
405 0 : if( ! rangeList )
406 0 : return NPERR_NO_ERROR;
407 :
408 0 : ::std::list<XPlugin_Impl*>& rList = PluginManager::get().getPlugins();
409 0 : ::std::list<XPlugin_Impl*>::iterator iter;
410 0 : XPlugin_Impl* pPlugin = NULL;
411 0 : PluginStream* pStream = NULL;
412 0 : for( iter = rList.begin(); iter!= rList.end(); ++iter )
413 : {
414 0 : pStream = (*iter)->getStreamFromNPStream( stream );
415 0 : if( pStream )
416 : {
417 0 : pPlugin = *iter;
418 0 : break;
419 : }
420 : }
421 0 : if( ! pPlugin )
422 0 : return NPERR_INVALID_INSTANCE_ERROR;
423 0 : if( ! pStream || pStream->getStreamType() != InputStream )
424 0 : return NPERR_FILE_NOT_FOUND;
425 :
426 0 : PluginInputStream* pInputStream = (PluginInputStream*)pStream;
427 0 : sal_Int8* pBytes = NULL;
428 0 : int nBytes = 0;
429 0 : pPlugin->enterPluginCallback();
430 0 : while( rangeList )
431 : {
432 0 : if( pBytes && nBytes < (int)rangeList->length )
433 : {
434 0 : delete [] pBytes;
435 0 : pBytes = NULL;
436 : }
437 0 : if( ! pBytes )
438 0 : pBytes = new sal_Int8[ nBytes = rangeList->length ];
439 : int nRead =
440 0 : pInputStream->read( rangeList->offset, pBytes, rangeList->length );
441 0 : int nPos = 0;
442 : int nNow;
443 0 : do
444 : {
445 0 : nNow = pPlugin->getPluginComm()->
446 : NPP_WriteReady( pPlugin->getNPPInstance(),
447 0 : stream );
448 0 : nNow = pPlugin->getPluginComm()->
449 : NPP_Write( pPlugin->getNPPInstance(),
450 : stream,
451 : rangeList->offset + nPos,
452 : nNow,
453 0 : pBytes+nPos );
454 0 : nPos += nNow;
455 0 : nRead -= nNow;
456 0 : } while( nRead > 0 && nNow );
457 0 : rangeList = rangeList->next;
458 : }
459 0 : pPlugin->leavePluginCallback();
460 :
461 0 : return NPERR_NO_ERROR;
462 : }
463 :
464 0 : void SAL_CALL NP_LOADDS NPN_Status( NPP instance, const char* message )
465 : {
466 : TRACE( "NPN_Status" );
467 0 : XPlugin_Impl* pImpl = XPluginManager_Impl::getXPluginFromNPP( instance );
468 0 : if( ! pImpl )
469 0 : return;
470 :
471 : try
472 : {
473 0 : pImpl->enterPluginCallback();
474 0 : pImpl->getPluginContext()->
475 0 : displayStatusText( pImpl, OStringToOUString( message, pImpl->getTextEncoding() ) );
476 0 : pImpl->leavePluginCallback();
477 : }
478 0 : catch( const ::com::sun::star::plugin::PluginException& )
479 : {
480 0 : pImpl->leavePluginCallback();
481 0 : return;
482 : }
483 : }
484 :
485 0 : const char* SAL_CALL NP_LOADDS NPN_UserAgent( NPP instance )
486 : {
487 0 : static char* pAgent = strdup( "Mozilla 3.0" );
488 :
489 0 : XPlugin_Impl* pImpl = XPluginManager_Impl::getXPluginFromNPP( instance );
490 0 : if( pImpl )
491 : {
492 0 : OUString UserAgent;
493 : try
494 : {
495 0 : pImpl->enterPluginCallback();
496 0 : UserAgent = pImpl->getPluginContext()->
497 0 : getUserAgent( pImpl );
498 0 : pImpl->leavePluginCallback();
499 0 : if( pAgent )
500 0 : free( pAgent );
501 0 : pAgent = strdup( OUStringToOString( UserAgent, pImpl->getTextEncoding() ).getStr() );
502 : }
503 0 : catch( const ::com::sun::star::plugin::PluginException& )
504 : {
505 0 : pImpl->leavePluginCallback();
506 0 : }
507 : }
508 :
509 : TRACES( "NPN_UserAgent: returning", pAgent );
510 :
511 0 : return pAgent;
512 : }
513 :
514 0 : void SAL_CALL NP_LOADDS NPN_Version( int* major, int* minor, int* net_major, int* net_minor )
515 : {
516 : TRACE( "NPN_Version" );
517 0 : *major = 4;
518 0 : *minor = 0;
519 0 : *net_major = 4;
520 0 : *net_minor = 5;
521 0 : }
522 :
523 0 : int32_t SAL_CALL NP_LOADDS NPN_Write( NPP instance, NPStream* stream, int32_t len,
524 : void* buffer )
525 : {
526 : TRACE( "NPN_Write" );
527 0 : XPlugin_Impl* pImpl = XPluginManager_Impl::getXPluginFromNPP( instance );
528 0 : if( ! pImpl )
529 0 : return 0;
530 :
531 0 : PluginStream* pStream = pImpl->getStreamFromNPStream( stream );
532 0 : if( ! pStream || pStream->getStreamType() != OutputStream )
533 0 : return 0;
534 :
535 0 : pImpl->enterPluginCallback();
536 0 : ::com::sun::star::uno::Sequence<sal_Int8> Bytes( (sal_Int8*)buffer, len );
537 0 : ((PluginOutputStream*)pStream)->getOutputStream()->writeBytes( Bytes );
538 0 : pImpl->leavePluginCallback();
539 :
540 0 : return len;
541 : }
542 :
543 :
544 0 : NPError SAL_CALL NP_LOADDS NPN_GetValue( NPP instance, NPNVariable variable, void* value )
545 : {
546 : TRACEN( "NPN_GetValue: ", variable );
547 0 : XPlugin_Impl* pImpl = XPluginManager_Impl::getXPluginFromNPP( instance );
548 :
549 0 : if( ! pImpl )
550 0 : return 0;
551 :
552 0 : NPError aResult( NPERR_NO_ERROR );
553 :
554 0 : switch( variable )
555 : {
556 : case NPNVxDisplay:
557 : // Unix only, handled in sysdep part
558 : case NPNVxtAppContext:
559 : // Unix only, handled in sysdep part
560 : default:
561 0 : aResult = NPERR_INVALID_PARAM;
562 0 : break;
563 : #ifdef MACOSX
564 : case 2000: // NPNVsupportsQuickDrawBool
565 : *(NPBool*)value = false;
566 : break;
567 : case 2001: // NPNVsupportsCoreGraphicsBool
568 : *(NPBool*)value = true;
569 : break;
570 : #endif
571 : case NPNVjavascriptEnabledBool:
572 : // no javascript
573 0 : *(NPBool*)value = false;
574 0 : break;
575 : case NPNVasdEnabledBool:
576 : // no SmartUpdate
577 0 : *(NPBool*)value = false;
578 0 : break;
579 : case NPNVisOfflineBool:
580 : // no offline browsing
581 0 : *(NPBool*)value = false;
582 0 : break;
583 : }
584 :
585 0 : return aResult;
586 : }
587 :
588 0 : void SAL_CALL NP_LOADDS NPN_ReloadPlugins(NPBool /*reloadPages*/)
589 : {
590 : TRACE( "NPN_ReloadPlugins" );
591 0 : }
592 :
593 :
594 0 : NPError SAL_CALL NP_LOADDS NPN_SetValue( NPP instance,
595 : NPPVariable variable,
596 : void* value )
597 : {
598 0 : NPError nError = NPERR_NO_ERROR;
599 : TRACEN( "NPN_SetValue ", variable );
600 : #ifdef MACOSX
601 : NPN_SetValue_Impl(instance, variable, value);
602 : #else
603 : (void)instance;
604 : (void)variable;
605 : (void)value;
606 : #endif
607 0 : return nError;
608 : }
609 :
610 0 : void SAL_CALL NP_LOADDS NPN_InvalidateRect(NPP instance, NPRect* /*invalidRect*/)
611 : {
612 : TRACE( "NPN_InvalidateRect" );
613 :
614 : #ifdef MACOSX
615 : NPN_ForceRedraw( instance );
616 : #else
617 : (void)instance;
618 : #endif
619 0 : }
620 :
621 0 : void SAL_CALL NP_LOADDS NPN_InvalidateRegion(NPP instance, NPRegion /*invalidRegion*/)
622 : {
623 : TRACE( "NPN_InvalidateRegion" );
624 :
625 : #ifdef MACOSX
626 : NPN_ForceRedraw( instance );
627 : #else
628 : (void)instance;
629 : #endif
630 0 : }
631 :
632 0 : void SAL_CALL NP_LOADDS NPN_ForceRedraw(NPP instance)
633 : {
634 : TRACE( "NPN_ForceRedraw" );
635 : #ifdef MACOSX
636 : NPN_ForceRedraw_Impl(instance);
637 : #else
638 : (void)instance;
639 : #endif
640 0 : }
641 :
642 0 : }
643 :
644 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|