bump product version to 5.0.4.1
[LibreOffice.git] / extensions / source / plugin / aqua / sysplug.mm
blob27134d03836011f6f1ac1c96c496ba09fc2928a4
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  ************************************************************************/
29 #include <config_lgpl.h>
31 #include <cstdarg>
33 #include <sys/types.h>
34 #include <signal.h>
35 #include <sys/wait.h>
37 #include "premac.h"
38 #include <Cocoa/Cocoa.h>
39 #include "postmac.h"
41 #include <osl/thread.h>
43 #include <plugin/impl.hxx>
45 extern NPNetscapeFuncs aNPNFuncs;
47 #include <tools/debug.hxx>
49 using namespace plugstringhelper;
51 using ::rtl::OUString;
52 using ::rtl::OUStringToOString;
54 #if OSL_DEBUG_LEVEL > 1
55 void TRACE( char const * s );
56 void TRACEN( char const * s, long n );
57 #else
58 #define TRACE(x)
59 #define TRACEN(x,n)
60 #endif
63 struct SysPlugData
65     MacPluginComm::NP_CGContext m_aCGContext;
66     NP_Port                     m_aNPPort;
67     NSView*                     m_pParentView;
68     NSView*                     m_pPlugView;
69     int                         m_nDrawingModel;
70     NSPoint                     m_aLastPlugViewOrigin;
71     bool                        m_bSetWindowOnDraw;
72     SysPlugData()
73     {
74         memset( this, 0, sizeof(*this) );
75     }
78 ::boost::shared_ptr<SysPlugData> CreateSysPlugData()
80     return ::boost::shared_ptr<SysPlugData>(new SysPlugData);
83 void XPlugin_Impl::SetSysPlugDataParentView(SystemEnvData const& rEnvData)
85     m_pSysPlugData->m_pParentView = rEnvData.mpNSView;
88 extern "C" {
90 void /*SAL_CALL NP_LOADDS*/  NPN_ForceRedraw_Impl(NPP instance)
92     TRACE( "NPN_ForceRedraw_Impl" );
93     XPlugin_Impl* pImpl = XPluginManager_Impl::getXPluginFromNPP( instance );
94     if( pImpl )
95     {
96         SysPlugData& rPlugData( pImpl->getSysPlugData() );
97         if( rPlugData.m_pPlugView )
98             [rPlugData.m_pPlugView setNeedsDisplay: YES];
99     }
102 NPError /*SAL_CALL NP_LOADDS*/  NPN_SetValue_Impl( NPP instance,
103                                           NPPVariable variable,
104                                           void* value )
106     TRACE( "NPN_SetValue_Impl" );
107     switch( variable )
108     {
109         case (NPPVariable)1000: // NPNVpluginDrawingModel
110         {
111             // ugly, but that's the way we need to do it
112             int nDrawingModel = (int)value;
114             TRACEN( "drawing model: ", nDrawingModel );
115             XPlugin_Impl* pImpl =
116                 XPluginManager_Impl::getXPluginFromNPP( instance );
117             if (pImpl)
118                 pImpl->getSysPlugData().m_nDrawingModel = nDrawingModel;
119         }
120         break;
121         default:
122         break;
123     }
124     return NPERR_NO_ERROR;
127 } // extern "C"
129 struct FakeEventRecord : public EventRecord
131     FakeEventRecord()
132     {
133         memset( this, 0, sizeof(EventRecord) );
134         ::GetGlobalMouse( &where );
135         when = ::TickCount();
136         modifiers = ::GetCurrentEventKeyModifiers();
137     }
141 @interface OOoPluginView : NSView
143     XPlugin_Impl*   m_pImpl;
144     MacPluginComm*  m_pCom;
146 -(id)initWithInstance: (XPlugin_Impl*)i_pImpl pluginComm: (MacPluginComm*)i_pCom frame: (NSRect)i_aRect;
147 -(void)drawRect: (NSRect)i_aRect;
148 -(BOOL)isOpaque;
149 -(BOOL)isFlipped;
151 // NSResponder
152 -(void)mouseMoved:   (NSEvent*)i_pEvent;
153 -(void)mouseDown:    (NSEvent*)i_pEvent;
154 -(void)mouseDragged: (NSEvent*)i_pEvent;
155 -(void)mouseUp:      (NSEvent*)i_pEvent;
156 -(void)rightMouseDown:    (NSEvent*)i_pEvent;
157 -(void)rightMouseDragged: (NSEvent*)i_pEvent;
158 -(void)rightMouseUp:      (NSEvent*)i_pEvent;
159 -(void)otherMouseDown:    (NSEvent*)i_pEvent;
160 -(void)otherMouseDragged: (NSEvent*)i_pEvent;
161 -(void)otherMouseUp:      (NSEvent*)i_pEvent;
162 -(void)mouseEntered: (NSEvent*)i_pEvent;
163 -(void)mouseExited:  (NSEvent*)i_pEvent;
164 @end
166 @implementation OOoPluginView
167 -(id)initWithInstance: (XPlugin_Impl*)i_pImpl pluginComm: (MacPluginComm*)i_pCom frame: (NSRect) i_aRect
169     if( (self = [super initWithFrame: i_aRect]) )
170     {
171         m_pImpl = i_pImpl;
172         m_pCom = i_pCom;
173     }
174     return self;
177 -(void)drawRect: (NSRect) i_aRect
179     (void) i_aRect; // unused
180     m_pCom->drawView( m_pImpl );
183 -(BOOL)isOpaque
185     return NO;
188 -(BOOL)isFlipped
190     return YES;
193 // NSResponder
194 -(void)mouseMoved:   (NSEvent*)i_pEvent
196     (void) i_pEvent; // unused
197     FakeEventRecord aRec;
198     aRec.what = osEvt + 18; // NPEventType_AdjustCursorEvent
199     m_pCom->NPP_HandleEvent( &m_pImpl->getNPPInstance(), &aRec );
202 -(void)mouseDown:    (NSEvent*)i_pEvent
204     (void) i_pEvent; // unused
205     FakeEventRecord aRec;
206     aRec.what = mouseDown;
207     m_pCom->NPP_HandleEvent( &m_pImpl->getNPPInstance(), &aRec );
210 -(void)mouseDragged: (NSEvent*)i_pEvent
212     (void) i_pEvent; // unused
213     FakeEventRecord aRec;
214     aRec.what = aRec.what = osEvt + 18; // NPEventType_AdjustCursorEvent
215     m_pCom->NPP_HandleEvent( &m_pImpl->getNPPInstance(), &aRec );
218 -(void)mouseUp:      (NSEvent*)i_pEvent
220     (void) i_pEvent; // unused
221     FakeEventRecord aRec;
222     aRec.what = mouseUp;
223     m_pCom->NPP_HandleEvent( &m_pImpl->getNPPInstance(), &aRec );
226 -(void)rightMouseDown:    (NSEvent*)i_pEvent
228     (void) i_pEvent; // unused
229     FakeEventRecord aRec;
230     aRec.what = mouseDown;
231     m_pCom->NPP_HandleEvent( &m_pImpl->getNPPInstance(), &aRec );
234 -(void)rightMouseDragged: (NSEvent*)i_pEvent
236     (void) i_pEvent; // unused
237     FakeEventRecord aRec;
238     aRec.what = aRec.what = osEvt + 18; // NPEventType_AdjustCursorEvent
239     m_pCom->NPP_HandleEvent( &m_pImpl->getNPPInstance(), &aRec );
242 -(void)rightMouseUp:      (NSEvent*)i_pEvent
244     (void) i_pEvent; // unused
245     FakeEventRecord aRec;
246     aRec.what = mouseUp;
247     m_pCom->NPP_HandleEvent( &m_pImpl->getNPPInstance(), &aRec );
250 -(void)otherMouseDown:    (NSEvent*)i_pEvent
252     (void) i_pEvent; // unused
253     FakeEventRecord aRec;
254     aRec.what = mouseDown;
255     m_pCom->NPP_HandleEvent( &m_pImpl->getNPPInstance(), &aRec );
258 -(void)otherMouseDragged: (NSEvent*)i_pEvent
260     (void) i_pEvent; // unused
261     FakeEventRecord aRec;
262     aRec.what = aRec.what = osEvt + 18; // NPEventType_AdjustCursorEvent
263     m_pCom->NPP_HandleEvent( &m_pImpl->getNPPInstance(), &aRec );
266 -(void)otherMouseUp:      (NSEvent*)i_pEvent
268     (void) i_pEvent; // unused
269     FakeEventRecord aRec;
270     aRec.what = mouseUp;
271     m_pCom->NPP_HandleEvent( &m_pImpl->getNPPInstance(), &aRec );
274 -(void)mouseEntered: (NSEvent*)i_pEvent
276     (void) i_pEvent; // unused
277     FakeEventRecord aRec;
278     aRec.what = aRec.what = osEvt + 18; // NPEventType_AdjustCursorEvent
279     m_pCom->NPP_HandleEvent( &m_pImpl->getNPPInstance(), &aRec );
282 -(void)mouseExited:  (NSEvent*)i_pEvent
284     (void) i_pEvent; // unused
285     FakeEventRecord aRec;
286     aRec.what = aRec.what = osEvt + 18; // NPEventType_AdjustCursorEvent
287     m_pCom->NPP_HandleEvent( &m_pImpl->getNPPInstance(), &aRec );
290 @end
293 MacPluginComm::MacPluginComm( const rtl::OUString& i_rMimetype, const rtl::OUString& i_rBundle, NSView* i_pParent )
294     : PluginComm( OUStringToOString( i_rBundle, RTL_TEXTENCODING_UTF8 ) ),
295       m_xBundle( NULL ),
296       m_hPlugLib( NULL ),
297       m_pNullTimer( NULL )
299     (void) i_rMimetype; // unused
300     (void) i_pParent; // unused
301     // initialize plugin function table
302     memset( &m_aNPPfuncs, 0, sizeof( m_aNPPfuncs ) );
304     // load the bundle
305     CFURLRef xURL = createURL( i_rBundle );
306     m_xBundle = CFBundleCreate( NULL, xURL );
307     CFRelease( xURL );
308     if( m_xBundle )
309     {
310         // ask the plugin library
311         // first get its location
312         CFURLRef xLibURL = CFBundleCopyExecutableURL( m_xBundle );
313         if( xLibURL )
314         {
315             // get the file system path
316             rtl::OUString aModuleURL( CFURLtoOSLURL( xLibURL ) );
317             CFRelease( xLibURL );
318             m_hPlugLib = osl_loadModule( aModuleURL.pData, SAL_LOADMODULE_DEFAULT );
319             #if OSL_DEBUG_LEVEL > 1
320             if( ! m_hPlugLib )
321                 fprintf( stderr, "module %s could not be loaded\n", OUStringToOString( aModuleURL, RTL_TEXTENCODING_UTF8 ).getStr() );
322             #endif
323         }
324         #if OSL_DEBUG_LEVEL > 1
325         else
326             fprintf( stderr, "bundle %s has no exectutable URL\n", OUStringToOString( i_rBundle, RTL_TEXTENCODING_UTF8 ).getStr() );
327         #endif
328     }
329     else
330     {
331         #if OSL_DEBUG_LEVEL > 1
332         fprintf( stderr, "bundle %s could not be loaded\n", OUStringToOString( i_rBundle, RTL_TEXTENCODING_UTF8 ).getStr() );
333         #endif
334     }
336     DBG_ASSERT( m_xBundle && m_hPlugLib, "loading plugin bundle failed!" );
339     m_aNPPfuncs.size = sizeof( m_aNPPfuncs );
340     m_aNPPfuncs.version = 0;
343     m_eCall = eNP_Initialize;
344     execute();
348 MacPluginComm::~MacPluginComm()
350     if( m_hPlugLib )
351     {
352         // NPP_Shutdown();
353         NPError (*pShutdown)();
354         if( retrieveFunction( "NP_Shutdown", (void**)&pShutdown ) )
355         {
356             NPError nErr = (*pShutdown)(); (void)nErr;
357             DBG_ASSERT( nErr == NPERR_NO_ERROR, "NP_Shutdown() failed!" );
358         }
359         osl_unloadModule( m_hPlugLib );
360     }
361     if( m_xBundle )
362         CFRelease( m_xBundle );
366 sal_Bool MacPluginComm::retrieveFunction( const char* i_pName, void** o_ppFunc ) const
368     if( ! m_hPlugLib || ! o_ppFunc )
369         return sal_False;
371     *o_ppFunc = (void*)osl_getAsciiFunctionSymbol( m_hPlugLib, i_pName );
373     if( ! *o_ppFunc && m_xBundle )
374     {
375         rtl::OUString aName( OUString::createFromAscii( *i_pName == '_' ? i_pName+1 : i_pName ) );
376         CFStringRef xName = createString( aName );
377         if( xName )
378         {
379             *o_ppFunc =  CFBundleGetFunctionPointerForName( m_xBundle, xName );
380             CFRelease( xName );
381         }
382     }
384     return (*o_ppFunc != NULL);
387 IMPL_LINK_NOARG(MacPluginComm, NullTimerHdl)
389     // note: this is a Timer handler, we are already protected by the SolarMutex
391     FakeEventRecord aRec;
392     aRec.what = nullEvent;
393     aRec.where.h = aRec.where.v = 20000;
395     for( std::list< XPlugin_Impl* >::iterator it = m_aNullEventClients.begin();
396          it != m_aNullEventClients.end(); ++it )
397     {
398         SysPlugData& rPlugData( (*it)->getSysPlugData() );
399         if( rPlugData.m_pPlugView ) // for safety do not dispatch null events before first NPP_SetWindow
400             (*m_aNPPfuncs.event)( &(*it)->getNPPInstance(), &aRec );
401     }
403     return 0;
408 long MacPluginComm::doIt()
410     long nRet = 0;
411     switch( m_eCall )
412     {
413     case eNP_Initialize:
414     {
415         TRACE( "eNP_Initialize" );
416         NPError (*pInit)( NPNetscapeFuncs* );
417         if( retrieveFunction( "NP_Initialize", (void**)&pInit ) )
418         {
419             nRet = (*pInit)( &aNPNFuncs );
421             NPError nErr = NPERR_NO_ERROR;
422             NPError (*pEntry)( NPPluginFuncs* );
423             retrieveFunction( "NP_GetEntryPoints", (void**)&pEntry );
424             nErr = (*pEntry)( &m_aNPPfuncs );
426             DBG_ASSERT( nErr == NPERR_NO_ERROR, "NP_GetEntryPoints() failed!" );
427         }
428         else
429         {
430             nRet = NPERR_GENERIC_ERROR;
431         }
432         DBG_ASSERT( nRet == NPERR_NO_ERROR, "### NP_Initialize() failed!" );
433     }
434     break;
435     case eNPP_Destroy:
436         if( m_aNullEventClients.empty() )
437             delete m_pNullTimer, m_pNullTimer = NULL;
439         TRACE( "eNPP_Destroy" );
440         nRet = (m_aNPPfuncs.destroy
441                 ? (*m_aNPPfuncs.destroy)(
442                     (NPP)m_aArgs[0],
443                     (NPSavedData**)m_aArgs[1] )
444                 : NPERR_GENERIC_ERROR);
445         break;
446     case eNPP_DestroyStream:
447         TRACE( "eNPP_DestroyStream" );
448         nRet =  (m_aNPPfuncs.destroystream
449                  ? (*m_aNPPfuncs.destroystream)(
450                      (NPP)m_aArgs[0],
451                      (NPStream*)m_aArgs[1],
452                      (NPError)(sal_IntPtr)m_aArgs[2] )
453                  : NPERR_GENERIC_ERROR);
454         break;
455     case eNPP_New:
456         TRACE( "eNPP_New" );
457         nRet = (m_aNPPfuncs.newp
458                 ? (*m_aNPPfuncs.newp)(
459                     (NPMIMEType)m_aArgs[0],
460                     (NPP)m_aArgs[1],
461                     (uint16_t)(sal_IntPtr)m_aArgs[2],
462                     (int16_t)(sal_IntPtr)m_aArgs[3],
463                     (char**)m_aArgs[4],
464                     (char**)m_aArgs[5],
465                     (NPSavedData*)m_aArgs[6] )
466                 : NPERR_GENERIC_ERROR);
468         if( ! m_pNullTimer && m_aNPPfuncs.event )
469         {
470             m_pNullTimer = new AutoTimer();
471             m_pNullTimer->SetTimeout( 50 );
472             m_pNullTimer->SetTimeoutHdl( LINK( this, MacPluginComm, NullTimerHdl ) );
473             m_pNullTimer->Start();
474         }
476         break;
477     case eNPP_NewStream:
478         TRACE( "eNPP_NewStream" );
479         nRet = (m_aNPPfuncs.newstream
480                 ? (*m_aNPPfuncs.newstream)(
481                     (NPP)m_aArgs[0],
482                     (NPMIMEType)m_aArgs[1],
483                     (NPStream*)m_aArgs[2],
484                     (NPBool)(sal_IntPtr)m_aArgs[3],
485                     (uint16_t*)m_aArgs[4] )
486                 : NPERR_GENERIC_ERROR);
487         break;
488     case eNPP_Print:
489         TRACE( "eNPP_Print" );
490         if (m_aNPPfuncs.print)
491             (*m_aNPPfuncs.print)(
492                 (NPP)m_aArgs[0],
493                 (NPPrint*)m_aArgs[1] );
494         break;
495     case eNPP_SetWindow:
496     {
497         TRACE( "eNPP_SetWindow" );
498         nRet = (m_aNPPfuncs.setwindow
499                 ? (*m_aNPPfuncs.setwindow)(
500                     (NPP)m_aArgs[0],
501                     (NPWindow*)m_aArgs[1] )
502                 : NPERR_GENERIC_ERROR);
504         break;
505     }
506     case eNPP_HandleEvent:
507     {
508         TRACE( "eNPP_HandleEvent" );
509         nRet = (m_aNPPfuncs.event
510                 ? (*m_aNPPfuncs.event)(
511                     (NPP)m_aArgs[0],
512                     m_aArgs[1] )
513                 : NPERR_GENERIC_ERROR);
515         break;
516     }
517     case eNPP_StreamAsFile:
518         TRACE( "eNPP_StreamAsFile" );
519         if (m_aNPPfuncs.asfile)
520             (*m_aNPPfuncs.asfile)(
521                 (NPP)m_aArgs[0],
522                 (NPStream*)m_aArgs[1],
523                 (char*)m_aArgs[2] );
524         break;
525     case eNPP_URLNotify:
526         TRACE( "eNPP_URLNotify" );
527         if (m_aNPPfuncs.urlnotify)
528             (*m_aNPPfuncs.urlnotify)(
529                 (NPP)m_aArgs[0],
530                 (char*)m_aArgs[1],
531                 (NPReason)(sal_IntPtr)m_aArgs[2],
532                 m_aArgs[3] );
533         break;
534     case eNPP_Write:
535         TRACEN( "eNPP_Write n=", (int32_t)m_aArgs[3] );
536         nRet = (m_aNPPfuncs.write
537                 ? (*m_aNPPfuncs.write)(
538                     (NPP)m_aArgs[0],
539                     (NPStream*)m_aArgs[1],
540                     (int32_t)m_aArgs[2],
541                     (int32_t)m_aArgs[3],
542                     m_aArgs[4] )
543                 : 0);
544         break;
545     case eNPP_WriteReady:
546         TRACE( "eNPP_WriteReady" );
547         nRet = (m_aNPPfuncs.writeready
548                 ? (*m_aNPPfuncs.writeready)(
549                     (NPP)m_aArgs[0],
550                     (NPStream*)m_aArgs[1] )
551                 : 0);
552         break;
553     case eNPP_GetValue:
554         TRACE( "eNPP_GetValue" );
555         nRet = (m_aNPPfuncs.getvalue
556                 ? (*m_aNPPfuncs.getvalue)(
557                     (NPP)m_aArgs[0],
558                     (NPPVariable)(int)m_aArgs[1],
559                     m_aArgs[2] )
560                 : NPERR_GENERIC_ERROR);
561         break;
562     case eNPP_SetValue:
563         TRACE( "eNPP_SetValue" );
564         nRet = (m_aNPPfuncs.setvalue
565                 ? (*m_aNPPfuncs.setvalue)(
566                     (NPP)m_aArgs[0],
567                     (NPNVariable)(int)m_aArgs[1],
568                     m_aArgs[2] )
569                 : NPERR_GENERIC_ERROR);
570         break;
571     case eNPP_Shutdown:
572     {
573         TRACE( "eNPP_Shutdown" );
574         NPP_ShutdownUPP pFunc;
575         if (retrieveFunction( "NPP_Shutdown", (void**)&pFunc ))
576             (*pFunc)();
577     }
578     break;
579     case eNPP_Initialize:
580         TRACE( "eNPP_Initialize" );
581         OSL_FAIL( "NPP_Initialize: not implemented!" );
582         break;
583     case eNPP_GetJavaClass:
584         TRACE( "eNPP_GetJavaClass" );
585         OSL_FAIL( "NPP_GetJavaClass: not implemented!" );
586         break;
587     }
588     return nRet;
592 NPError MacPluginComm::NPP_Destroy( XPlugin_Impl* i_pImpl, NPSavedData** save )
594     // remove from NullEvent timer
595     m_aNullEventClients.remove( i_pImpl );
597     NPError nErr = NPP_Destroy( &i_pImpl->getNPPInstance(), save );
599     // release plugin view
600     SysPlugData& rPlugData( i_pImpl->getSysPlugData() );
601     if( rPlugData.m_pPlugView )
602     {
603         [rPlugData.m_pPlugView removeFromSuperview];
604         [rPlugData.m_pPlugView release];
605         rPlugData.m_pPlugView = nil;
606     }
608     return nErr;
612 NPError MacPluginComm::NPP_Destroy( NPP instance, NPSavedData** save )
614     DBG_ASSERT( m_aNPPfuncs.destroy, "### NPP_Destroy(): null pointer in NPP functions table!" );
615     m_eCall = eNPP_Destroy;
616     m_aArgs[0] = (void*)instance;
617     m_aArgs[1] = (void*)save;
618     return (NPError)execute();
622 NPError MacPluginComm::NPP_DestroyStream( NPP instance, NPStream* stream, NPError reason )
624     DBG_ASSERT( m_aNPPfuncs.destroystream, "### NPP_DestroyStream(): null pointer in NPP functions table!" );
625     m_eCall = eNPP_DestroyStream;
626     m_aArgs[0] = (void*)instance;
627     m_aArgs[1] = (void*)stream;
628     m_aArgs[2] = (void*)(intptr_t)reason;
629     return (NPError)execute();
633 NPError MacPluginComm::NPP_New( NPMIMEType pluginType, NPP instance, uint16_t mode, int16_t argc,
634                                   char* argn[], char* argv[], NPSavedData *saved )
636     XPlugin_Impl* pImpl = XPluginManager_Impl::getXPluginFromNPP( instance );
637     DBG_ASSERT( pImpl, "no instance found" );
639     if( pImpl ) // sanity check
640         m_aNullEventClients.push_back( pImpl );
642     DBG_ASSERT( m_aNPPfuncs.newp, "### NPP_New(): null pointer in NPP functions table!" );
643     #if OSL_DEBUG_LEVEL > 1
644     fprintf( stderr, "NPP_New( %s. %p, %d, %d",
645              pluginType, instance, (int)mode, (int)argc );
646     for( int16_t i = 0; i < argc; i++ )
647     fprintf( stderr, "\n%s = %s", argn[i], argv[i] );
648     fprintf( stderr, ", %p )\n", saved );
649     #endif
650     m_eCall = eNPP_New;
651     m_aArgs[0] = (void*)pluginType;
652     m_aArgs[1] = (void*)instance;
653     m_aArgs[2] = (void*)(intptr_t)mode;
654     m_aArgs[3] = (void*)(intptr_t)argc;
655     m_aArgs[4] = (void*)argn;
656     m_aArgs[5] = (void*)argv;
657     m_aArgs[6] = (void*)saved;
659     return (NPError)execute();
663 NPError MacPluginComm::NPP_NewStream( NPP instance, NPMIMEType type, NPStream* stream,
664                                         NPBool seekable, uint16_t* stype )
666     DBG_ASSERT( m_aNPPfuncs.newstream, "### NPP_NewStream(): null pointer in NPP functions table!" );
667     m_eCall = eNPP_NewStream;
668     m_aArgs[0] = (void*)instance;
669     m_aArgs[1] = (void*)type;
670     m_aArgs[2] = (void*)stream;
671     m_aArgs[3] = (void*)(intptr_t)seekable;
672     m_aArgs[4] = (void*)stype;
673     return (NPError)execute();
677 void MacPluginComm::NPP_Print( NPP instance, NPPrint* platformPrint )
679     DBG_ASSERT( m_aNPPfuncs.print, "### NPP_Print(): null pointer in NPP functions table!" );
680     m_eCall = eNPP_Print;
681     m_aArgs[0] = (void*)instance;
682     m_aArgs[1] = (void*)platformPrint;
683     execute();
687 NPError MacPluginComm::NPP_SetWindow( NPP instance, NPWindow* window )
689     DBG_ASSERT( m_aNPPfuncs.setwindow, "### NPP_SetWindow(): null pointer in NPP functions table!" );
690     m_eCall = eNPP_SetWindow;
691     m_aArgs[0] = (void*)instance;
692     m_aArgs[1] = (void*)window;
693     return (NPError)execute();
697 NPError MacPluginComm::NPP_HandleEvent( NPP instance, void* event )
699     DBG_ASSERT( m_aNPPfuncs.event, "### NPP_HandleEvent(): null pointer in NPP functions table!" );
700     m_eCall = eNPP_HandleEvent;
701     m_aArgs[0] = (void*)instance;
702     m_aArgs[1] = event;
703     return (NPError)execute();
707 void MacPluginComm::NPP_StreamAsFile( NPP instance, NPStream* stream, const char* fname )
709     DBG_ASSERT( m_aNPPfuncs.asfile, "### NPP_StreamAsFile(): null pointer in NPP functions table!" );
710     m_eCall = eNPP_StreamAsFile;
711     m_aArgs[0] = (void*)instance;
712     m_aArgs[1] = (void*)stream;
713     m_aArgs[2] = (void*)fname;
714     execute();
718 void MacPluginComm::NPP_URLNotify( NPP instance, const char* url, NPReason reason, void* notifyData )
720     DBG_ASSERT( m_aNPPfuncs.urlnotify, "### NPP_URLNotify(): null pointer in NPP functions table!" );
721     m_eCall = eNPP_URLNotify;
722     m_aArgs[0] = (void*)instance;
723     m_aArgs[1] = (void*)url;
724     m_aArgs[2] = (void*)(intptr_t)reason;
725     m_aArgs[3] = notifyData;
726     execute();
730 int32_t MacPluginComm::NPP_Write( NPP instance, NPStream* stream, int32_t offset, int32_t len, void* buffer )
732     DBG_ASSERT( m_aNPPfuncs.write, "### NPP_Write(): null pointer in NPP functions table!" );
733     m_eCall = eNPP_Write;
734     m_aArgs[0] = (void*)instance;
735     m_aArgs[1] = (void*)stream;
736     m_aArgs[2] = (void*)offset;
737     m_aArgs[3] = (void*)len;
738     m_aArgs[4] = buffer;
739     return (NPError)execute();
743 int32_t MacPluginComm::NPP_WriteReady( NPP instance, NPStream* stream )
745     DBG_ASSERT( m_aNPPfuncs.writeready, "### NPP_WriteReady(): null pointer in NPP functions table!" );
746     m_eCall = eNPP_WriteReady;
747     m_aArgs[0] = (void*)instance;
748     m_aArgs[1] = (void*)stream;
749     return execute();
753 NPError MacPluginComm::NPP_GetValue( NPP instance, NPPVariable variable, void *ret_value )
755     DBG_ASSERT( m_aNPPfuncs.getvalue, "### NPP_GetValue(): null pointer in NPP functions table!" );
756     m_eCall = eNPP_GetValue;
757     m_aArgs[0] = (void*)instance;
758     m_aArgs[1] = (void*)variable;
759     m_aArgs[2] = ret_value;
760     return (NPError)execute();
764 NPError MacPluginComm::NPP_SetValue( NPP instance, NPNVariable variable, void *set_value )
766     DBG_ASSERT( m_aNPPfuncs.setvalue, "### NPP_SetValue(): null pointer in NPP functions table!" );
767     m_eCall = eNPP_SetValue;
768     m_aArgs[0] = (void*)instance;
769     m_aArgs[1] = (void*)variable;
770     m_aArgs[2] = set_value;
771     return (NPError)execute();
775 void * MacPluginComm::NPP_GetJavaClass()
777     OSL_FAIL( "no java class available!" );
778     return 0;
782 NPError MacPluginComm::NPP_Initialize()
784     return NPERR_NO_ERROR;
788 void MacPluginComm::NPP_Shutdown()
790     m_eCall = eNPP_Shutdown;
791     execute();
795 NPError MacPluginComm::NPP_SetWindow( XPlugin_Impl* i_pImpl )
797     // update window NPWindow from view
798     SysPlugData& rPlugData( i_pImpl->getSysPlugData() );
800     // update plug view
801     NSRect aPlugRect = [rPlugData.m_pParentView frame];
802     aPlugRect.origin.x = aPlugRect.origin.y = 0;
803     if( ! rPlugData.m_pPlugView )
804     {
805         rPlugData.m_pPlugView = [[OOoPluginView alloc] initWithInstance: i_pImpl pluginComm: this frame: aPlugRect];
806         [rPlugData.m_pParentView addSubview: rPlugData.m_pPlugView];
807     }
808     else
809         [rPlugData.m_pPlugView setFrame: aPlugRect];
811     NPWindow* pNPWin = &i_pImpl->getNPWindow();
812     NSWindow* pWin = [rPlugData.m_pPlugView window];
813     NSRect aWinRect = [pWin frame];
814     NSRect aBounds = [rPlugData.m_pPlugView frame];
815     NSRect aVisibleBounds = [rPlugData.m_pPlugView visibleRect];
817     #if OSL_DEBUG_LEVEL > 1
818     fprintf( stderr, "visible bounds = %d+%d+%dx%d\n",
819              (int)aVisibleBounds.origin.x, (int)aVisibleBounds.origin.y,
820              (int)aVisibleBounds.size.width, (int)aVisibleBounds.size.height );
821     #endif
823     NSPoint aViewOrigin = [rPlugData.m_pPlugView convertPoint: NSZeroPoint toView: nil];
824     // save view origin so we can notice movement of the view in drawView
825     // in case of a moved view we need to reset the port/context
826     rPlugData.m_aLastPlugViewOrigin = aViewOrigin;
828     // convert view origin to topdown coordinates
829     aViewOrigin.y = aWinRect.size.height - aViewOrigin.y;
831     // same for clipping
832     NSPoint aClipOrigin = [rPlugData.m_pPlugView convertPoint: aVisibleBounds.origin toView: nil];
833     aClipOrigin.y = aWinRect.size.height - aClipOrigin.y;
835     #if OSL_DEBUG_LEVEL > 1
836     fprintf( stderr, "view origin: %d+%d, clip origin = %d+%d\n",
837              (int)aViewOrigin.x, (int)aViewOrigin.y,
838              (int)aClipOrigin.x, (int)aClipOrigin.y );
839     #endif
841     pNPWin->x                = aViewOrigin.x;
842     pNPWin->y                = aViewOrigin.y;
843     pNPWin->width            = aBounds.size.width;
844     pNPWin->height           = aBounds.size.height;
845     pNPWin->clipRect.left    = aClipOrigin.x;
846     pNPWin->clipRect.top     = aClipOrigin.y;
847     pNPWin->clipRect.right   = aClipOrigin.x + aVisibleBounds.size.width;
848     pNPWin->clipRect.bottom  = aClipOrigin.y + aVisibleBounds.size.height;
850     if( rPlugData.m_nDrawingModel == 1 )
851     {
852         rPlugData.m_aCGContext.window = reinterpret_cast<WindowRef>([pWin windowRef]);
853         pNPWin->window = &rPlugData.m_aCGContext;
854         rPlugData.m_aCGContext.context = reinterpret_cast<CGContextRef>([[pWin graphicsContext] graphicsPort]);
855         #if OSL_DEBUG_LEVEL > 1
856         fprintf( stderr, "window is %p, context is %p\n",
857                  rPlugData.m_aCGContext.window, rPlugData.m_aCGContext.context );
858         #endif
859     }
860     else
861     {
862         rPlugData.m_aNPPort.port = GetWindowPort( reinterpret_cast<WindowRef>([pWin windowRef]) );
863         rPlugData.m_aNPPort.portx = aClipOrigin.x;
864         rPlugData.m_aNPPort.porty = aClipOrigin.y;
865         pNPWin->window = &rPlugData.m_aNPPort;
866         #if OSL_DEBUG_LEVEL > 1
867         fprintf( stderr, "port is %p at (%d,%d)\n",
868                  rPlugData.m_aNPPort.port, (int)rPlugData.m_aNPPort.portx, (int)rPlugData.m_aNPPort.porty );
869         #endif
870     }
872     if( pNPWin->width == 0 || pNPWin->height == 0 || [rPlugData.m_pPlugView isHiddenOrHasHiddenAncestor] )
873         rPlugData.m_bSetWindowOnDraw = true;
875     NPError nErr = NPP_SetWindow( &i_pImpl->getNPPInstance(), &i_pImpl->getNPWindow() );
877     return nErr;
880 void MacPluginComm::drawView( XPlugin_Impl* i_pImpl )
882     SysPlugData& rPlugData( i_pImpl->getSysPlugData() );
884     // check if the view was moved since the last SetWindow
885     NSPoint aViewOrigin = [rPlugData.m_pPlugView convertPoint: NSZeroPoint toView: nil];
886     if( rPlugData.m_bSetWindowOnDraw ||
887         aViewOrigin.x != rPlugData.m_aLastPlugViewOrigin.x ||
888         aViewOrigin.y != rPlugData.m_aLastPlugViewOrigin.y )
889     {
890         NPP_SetWindow( i_pImpl );
891         rPlugData.m_bSetWindowOnDraw = false;
892     }
894     // send a paint event
895     NSWindow* pWin = [rPlugData.m_pPlugView window];
896     FakeEventRecord aRec;
897     aRec.what       =  updateEvt;
898     aRec.message    = (uint32_t)[pWin windowRef];
899     this->NPP_HandleEvent( &i_pImpl->getNPPInstance(), &aRec );
902 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */