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 : #include <cstdarg>
37 :
38 : #include <vcl/svapp.hxx>
39 :
40 : #include <plugin/unx/plugcon.hxx>
41 : #include <plugin/impl.hxx>
42 :
43 0 : std::vector<PluginConnector*> PluginConnector::allConnectors;
44 :
45 0 : PluginConnector::PluginConnector( int nSocket ) :
46 0 : Mediator( nSocket )
47 : {
48 0 : allConnectors.push_back( this );
49 0 : SetNewMessageHdl( LINK( this, PluginConnector, NewMessageHdl ) );
50 0 : }
51 :
52 0 : PluginConnector::~PluginConnector()
53 : {
54 0 : osl::MutexGuard aGuard( m_aUserEventMutex );
55 0 : for( std::vector< PluginConnector* >::iterator it = allConnectors.begin();
56 0 : it != allConnectors.end(); ++it )
57 : {
58 0 : if( *it == this )
59 : {
60 0 : allConnectors.erase( it );
61 0 : break;
62 : }
63 0 : }
64 0 : }
65 :
66 0 : IMPL_LINK( PluginConnector, NewMessageHdl, Mediator*, /*pMediator*/ )
67 : {
68 0 : osl::MutexGuard aGuard( m_aUserEventMutex );
69 0 : bool bFound = false;
70 0 : for( std::vector< PluginConnector* >::iterator it = allConnectors.begin();
71 0 : it != allConnectors.end() && bFound == false; ++it )
72 : {
73 0 : if( *it == this )
74 0 : bFound = true;
75 : }
76 0 : if( ! bFound )
77 0 : return 0;
78 0 : Application::PostUserEvent( LINK( this, PluginConnector, WorkOnNewMessageHdl ) );
79 0 : return 0;
80 : }
81 :
82 0 : IMPL_LINK( PluginConnector, WorkOnNewMessageHdl, Mediator*, /*pMediator*/ )
83 : {
84 0 : bool bFound = false;
85 0 : for( std::vector< PluginConnector* >::iterator it = allConnectors.begin();
86 0 : it != allConnectors.end() && bFound == false; ++it )
87 : {
88 0 : if( *it == this )
89 0 : bFound = true;
90 : }
91 0 : if( ! bFound )
92 0 : return 0;
93 :
94 : MediatorMessage* pMessage;
95 : CommandAtoms nCommand;
96 0 : while( (pMessage = GetNextMessage( sal_False )) )
97 : {
98 0 : nCommand = (CommandAtoms)pMessage->GetUINT32();
99 : SAL_INFO("extensions.plugin", GetCommandName(nCommand));
100 0 : switch( nCommand )
101 : {
102 : case eNPN_GetURL:
103 : {
104 0 : sal_uInt32 nInstance = pMessage->GetUINT32();
105 0 : NPP instance = m_aInstances[ nInstance ]->instance;
106 0 : char* pUrl = pMessage->GetString();
107 0 : char* pWindow = pMessage->GetString();
108 0 : NPError aRet = NPN_GetURL( instance, pUrl, pWindow );
109 : Respond( pMessage->m_nID,
110 0 : (char*)(&aRet), sizeof( NPError ), NULL );
111 0 : delete [] pUrl;
112 0 : delete [] pWindow;
113 : }
114 0 : break;
115 : case eNPN_GetURLNotify:
116 : {
117 0 : sal_uInt32 nInstance = pMessage->GetUINT32();
118 0 : NPP instance = m_aInstances[ nInstance ]->instance;
119 0 : char* pUrl = pMessage->GetString();
120 0 : char* pWindow = pMessage->GetString();
121 0 : void** pNotifyData = (void**)pMessage->GetBytes();
122 : NPError aRet = NPN_GetURLNotify( instance, pUrl, pWindow,
123 0 : *pNotifyData );
124 : Respond( pMessage->m_nID,
125 0 : (char*)(&aRet), sizeof( NPError ), NULL );
126 0 : delete [] pUrl;
127 0 : delete [] pWindow;
128 0 : delete [] pNotifyData;
129 : }
130 0 : break;
131 : case eNPN_DestroyStream:
132 : {
133 0 : sal_uInt32 nInstance = pMessage->GetUINT32();
134 0 : NPP instance = m_aInstances[ nInstance ]->instance;
135 0 : sal_uInt32 nFileID = pMessage->GetUINT32();
136 0 : char* pUrl = pMessage->GetString();
137 0 : NPError* pReason = (NPError*)pMessage->GetBytes();
138 0 : NPError aRet = NPERR_FILE_NOT_FOUND;
139 0 : if( nFileID < static_cast<sal_uInt32>(m_aNPWrapStreams.size()) )
140 : {
141 0 : if( ! strcmp( m_aNPWrapStreams[ nFileID ]->url, pUrl ) )
142 : {
143 : aRet =
144 0 : NPN_DestroyStream( instance, m_aNPWrapStreams[ nFileID ],
145 0 : *pReason );
146 0 : m_aNPWrapStreams.erase( m_aNPWrapStreams.begin() + nFileID );
147 : }
148 : else
149 : SAL_WARN(
150 : "extensions.plugin",
151 : "StreamID " << nFileID << " has incoherent urls "
152 : << pUrl << " and "
153 : << m_aNPWrapStreams[nFileID]->url);
154 : }
155 : else
156 : SAL_WARN(
157 : "extensions.plugin",
158 : "nonexistent StreamID " << nFileID);
159 :
160 : Respond( pMessage->m_nID,
161 0 : (char*)(&aRet), sizeof( NPError ), NULL );
162 :
163 0 : delete [] pUrl;
164 0 : delete [] pReason;
165 : }
166 0 : break;
167 : case eNPN_NewStream:
168 : {
169 0 : sal_uInt32 nInstance = pMessage->GetUINT32();
170 0 : NPP instance = m_aInstances[ nInstance ]->instance;
171 0 : NPMIMEType pType = pMessage->GetString();
172 0 : char* pTarget = pMessage->GetString();
173 :
174 0 : NPStream* pStream = NULL;
175 :
176 0 : NPError aRet = NPN_NewStream( instance, pType, pTarget, &pStream );
177 :
178 0 : if( aRet != NPERR_NO_ERROR )
179 : {
180 0 : sal_uInt32 nDummy = 0;
181 : Respond( pMessage->m_nID,
182 : (char*)&aRet, sizeof( aRet ),
183 : "", 0,
184 : &nDummy, sizeof(sal_uInt32),
185 : &nDummy, sizeof(sal_uInt32),
186 0 : NULL );
187 : }
188 : else
189 : {
190 0 : m_aNPWrapStreams.push_back( pStream );
191 :
192 0 : sal_uLong nLen = strlen( pStream->url );
193 : Respond( pMessage->m_nID,
194 : (char*)&aRet, sizeof( aRet ),
195 : pStream->url, nLen,
196 : &pStream->end, sizeof(sal_uInt32),
197 : &pStream->lastmodified, sizeof(sal_uInt32),
198 0 : NULL );
199 : }
200 :
201 0 : delete [] pTarget;
202 0 : delete [] pType;
203 : }
204 0 : break;
205 : case eNPN_PostURLNotify:
206 : {
207 0 : sal_uInt32 nInstance = pMessage->GetUINT32();
208 0 : NPP instance = m_aInstances[ nInstance ]->instance;
209 0 : char* pUrl = pMessage->GetString();
210 0 : char* pTarget = pMessage->GetString();
211 0 : sal_uInt32 nLen = pMessage->GetUINT32();
212 0 : char* pBuf = (char*)pMessage->GetBytes();
213 0 : NPBool* pFile = (NPBool*)pMessage->GetBytes();
214 0 : void** pNData = (void**)pMessage->GetBytes();
215 : NPError aRet =
216 0 : NPN_PostURLNotify( instance, pUrl, pTarget, nLen, pBuf, *pFile, *pNData );
217 0 : Respond( pMessage->m_nID, (char*)&aRet, sizeof( aRet ), NULL );
218 0 : delete [] pUrl;
219 0 : delete [] pTarget;
220 0 : delete [] pBuf;
221 0 : delete [] pFile;
222 0 : delete [] pNData;
223 : }
224 0 : break;
225 : case eNPN_PostURL:
226 : {
227 0 : sal_uInt32 nInstance = pMessage->GetUINT32();
228 0 : NPP instance = m_aInstances[ nInstance ]->instance;
229 0 : char* pUrl = pMessage->GetString();
230 0 : char* pWindow = pMessage->GetString();
231 0 : sal_uInt32 nLen = pMessage->GetUINT32();
232 0 : char* pBuf = (char*)pMessage->GetBytes();
233 0 : NPBool* pFile = (NPBool*)pMessage->GetBytes();
234 : NPError aRet =
235 0 : NPN_PostURL( instance, pUrl, pWindow, nLen, pBuf, *pFile );
236 0 : Respond( pMessage->m_nID, (char*)&aRet, sizeof( aRet ), NULL );
237 0 : delete [] pUrl;
238 0 : delete [] pWindow;
239 0 : delete [] pBuf;
240 0 : delete [] pFile;
241 : }
242 0 : break;
243 : case eNPN_RequestRead:
244 : {
245 0 : sal_uInt32 nFileID = pMessage->GetUINT32();
246 0 : NPStream* pStream = m_aNPWrapStreams[ nFileID ];
247 0 : sal_uInt32 nRanges = pMessage->GetUINT32();
248 0 : sal_uInt32* pArray = (sal_uInt32*)pMessage->GetBytes();
249 : // build ranges table
250 0 : NPByteRange* pFirst = new NPByteRange;
251 0 : NPByteRange* pRun = pFirst;
252 0 : for( sal_uInt32 n = 0; n < nRanges; n++ )
253 : {
254 0 : pRun->offset = pArray[ 2*n ];
255 0 : pRun->length = pArray[ 2*n+1 ];
256 0 : pRun->next = n < nRanges-1 ? new NPByteRange : NULL;
257 0 : pRun = pRun->next;
258 : }
259 0 : NPError aRet = NPN_RequestRead( pStream, pFirst );
260 0 : Respond( pMessage->m_nID, (char*)&aRet, sizeof( aRet ), NULL );
261 0 : while( pFirst )
262 : {
263 0 : pRun = pFirst->next;
264 0 : delete pFirst;
265 0 : pFirst = pRun;
266 : }
267 0 : delete [] pArray;
268 : }
269 0 : break;
270 : case eNPN_Status:
271 : {
272 0 : sal_uInt32 nInstance = pMessage->GetUINT32();
273 0 : NPP instance = m_aInstances[ nInstance ]->instance;
274 0 : char* pString = pMessage->GetString();
275 0 : NPN_Status( instance, pString );
276 0 : delete [] pString;
277 : }
278 0 : break;
279 : case eNPN_Version:
280 : {
281 : int major, minor, net_major, net_minor;
282 0 : NPN_Version( &major, &minor, &net_major, &net_minor );
283 : Respond( pMessage->m_nID,
284 : (char*)&major, sizeof( int ),
285 : &minor, sizeof( int ),
286 : &net_major, sizeof( int ),
287 : &net_minor, sizeof( int ),
288 0 : NULL );
289 : }
290 0 : break;
291 : case eNPN_Write:
292 : {
293 0 : sal_uInt32 nInstance = pMessage->GetUINT32();
294 0 : NPP instance = m_aInstances[ nInstance ]->instance;
295 0 : sal_uInt32 nFileID = pMessage->GetUINT32();
296 0 : NPStream* pStream = m_aNPWrapStreams[ nFileID ];
297 0 : sal_Int32 nLen = pMessage->GetUINT32();
298 0 : void* pBuffer = pMessage->GetBytes();
299 0 : sal_Int32 nRet = NPN_Write( instance, pStream, nLen, pBuffer );
300 : Respond( pMessage->m_nID,
301 : (char*)&nRet, sizeof( nRet ),
302 0 : NULL );
303 0 : delete [] (char*)pBuffer;
304 0 : delete instance;
305 : }
306 0 : break;
307 : case eNPN_UserAgent:
308 : {
309 0 : sal_uInt32 nInstance = pMessage->GetUINT32();
310 0 : NPP instance = m_aInstances[ nInstance ]->instance;
311 0 : const char* pAnswer = NPN_UserAgent( instance );
312 : Respond( pMessage->m_nID,
313 0 : (char*)pAnswer, strlen( pAnswer ),
314 0 : NULL );
315 : }
316 0 : break;
317 : default:
318 : SAL_WARN(
319 : "extensions.plugin",
320 : "caught unknown NPN request " << +nCommand);
321 : }
322 :
323 0 : delete pMessage;
324 : }
325 0 : return 0;
326 : }
327 :
328 : #define GET_INSTANCE() \
329 : sal_uInt32 nInstance; \
330 : nInstance = GetNPPID( instance );
331 :
332 : #define GET_INSTANCE_RET( err ) \
333 : GET_INSTANCE() \
334 : if( nInstance == PluginConnector::UnknownNPPID ) \
335 : return err
336 :
337 :
338 : #define POST_INSTANCE() (char*)&nInstance, sizeof( nInstance )
339 :
340 0 : NPError UnxPluginComm::NPP_Destroy( NPP instance, NPSavedData** save )
341 : {
342 0 : NPError aRet = NPERR_GENERIC_ERROR;
343 0 : GET_INSTANCE_RET( aRet );
344 : MediatorMessage* pMes =
345 : Transact( eNPP_Destroy,
346 : POST_INSTANCE(),
347 0 : NULL );
348 0 : if( ! pMes )
349 0 : return NPERR_GENERIC_ERROR;
350 0 : delete pMes;
351 :
352 : pMes = Transact( eNPP_DestroyPhase2,
353 : POST_INSTANCE(),
354 0 : NULL );
355 0 : if( ! pMes )
356 0 : return NPERR_GENERIC_ERROR;
357 :
358 0 : aRet = GetNPError( pMes );
359 : sal_uLong nSaveBytes;
360 0 : void* pSaveData = pMes->GetBytes( nSaveBytes );
361 0 : if( nSaveBytes == 4 && *(sal_uInt32*)pSaveData == 0 )
362 0 : *save = NULL;
363 : else
364 : {
365 0 : *save = new NPSavedData;
366 0 : (*save)->len = nSaveBytes;
367 0 : (*save)->buf = pSaveData;
368 : }
369 0 : delete pMes;
370 :
371 0 : return aRet;
372 : }
373 :
374 0 : NPError UnxPluginComm::NPP_DestroyStream( NPP instance, NPStream* stream, NPError reason )
375 : {
376 0 : NPError aRet = NPERR_GENERIC_ERROR;
377 0 : GET_INSTANCE_RET( aRet );
378 0 : sal_uInt32 nFileID = GetStreamID( stream );
379 0 : if( nFileID == PluginConnector::UnknownStreamID )
380 0 : return NPERR_GENERIC_ERROR;
381 :
382 : MediatorMessage* pMes =
383 : Transact( eNPP_DestroyStream,
384 : POST_INSTANCE(),
385 : &nFileID, sizeof( nFileID ),
386 : &reason, sizeof( reason ),
387 0 : NULL );
388 0 : m_aNPWrapStreams.erase( m_aNPWrapStreams.begin() + nFileID );
389 0 : if( ! pMes )
390 0 : return NPERR_GENERIC_ERROR;
391 :
392 0 : aRet = GetNPError( pMes );
393 0 : delete pMes;
394 0 : return aRet;
395 : }
396 :
397 0 : void* UnxPluginComm::NPP_GetJavaClass()
398 : {
399 0 : return NULL;
400 : }
401 :
402 0 : NPError UnxPluginComm::NPP_Initialize()
403 : {
404 : MediatorMessage* pMes =
405 : Transact( eNPP_Initialize,
406 0 : NULL );
407 0 : if( ! pMes )
408 0 : return NPERR_GENERIC_ERROR;
409 :
410 0 : NPError aRet = GetNPError( pMes );
411 0 : delete pMes;
412 0 : return aRet;
413 : }
414 :
415 0 : NPError UnxPluginComm::NPP_New( NPMIMEType pluginType, NPP instance, uint16_t mode, int16_t argc,
416 : char* argn[], char* argv[], NPSavedData *saved )
417 : {
418 : m_aInstances.push_back(
419 : new ConnectorInstance( instance, pluginType, 0,
420 : NULL, 0, NULL, 0,
421 : saved ? (char*)saved->buf : NULL,
422 0 : saved ? saved->len : 0 ) );
423 :
424 : char *pArgnBuf, *pArgvBuf;
425 0 : size_t nArgnLen = 0, nArgvLen = 0;
426 : int i;
427 0 : for( i = 0; i < argc; i++ )
428 : {
429 0 : nArgnLen += strlen( argn[i] ) +1;
430 0 : nArgvLen += strlen( argv[i] ) +1;
431 : }
432 0 : pArgnBuf = new char[ nArgnLen ];
433 0 : pArgvBuf = new char[ nArgvLen ];
434 0 : char* pRunArgn = pArgnBuf;
435 0 : char* pRunArgv = pArgvBuf;
436 0 : for( i = 0; i < argc; i++ )
437 : {
438 0 : strcpy( pRunArgn, argn[i] );
439 0 : strcpy( pRunArgv, argv[i] );
440 0 : pRunArgn += strlen( argn[i] ) +1;
441 0 : pRunArgv += strlen( argv[i] ) +1;
442 : }
443 :
444 : MediatorMessage* pMes;
445 0 : if( saved )
446 : pMes =
447 : Transact( eNPP_New,
448 : pluginType, strlen( pluginType ),
449 : &mode, sizeof( mode ),
450 : &argc, sizeof( argc ),
451 : pArgnBuf, nArgnLen,
452 : pArgvBuf, nArgvLen,
453 : saved->buf, static_cast<size_t>(saved->len),
454 0 : NULL );
455 : else
456 : pMes =
457 : Transact( eNPP_New,
458 : pluginType, strlen( pluginType ),
459 : &mode, sizeof( mode ),
460 : &argc, sizeof( argc ),
461 : pArgnBuf, nArgnLen,
462 : pArgvBuf, nArgvLen,
463 : "0000", size_t(4),
464 0 : NULL );
465 0 : delete [] pArgnBuf;
466 0 : delete [] pArgvBuf;
467 0 : if( ! pMes )
468 0 : return NPERR_GENERIC_ERROR;
469 :
470 0 : NPError aRet = GetNPError( pMes );
471 0 : delete pMes;
472 :
473 0 : return aRet;
474 : }
475 :
476 0 : NPError UnxPluginComm::NPP_NewStream( NPP instance, NPMIMEType type, NPStream* stream,
477 : NPBool seekable, uint16_t* stype )
478 : {
479 0 : NPError aRet = NPERR_GENERIC_ERROR;
480 0 : GET_INSTANCE_RET( aRet );
481 :
482 0 : m_aNPWrapStreams.push_back( stream );
483 : MediatorMessage* pMes =
484 : Transact( eNPP_NewStream,
485 : POST_INSTANCE(),
486 : type, strlen( type ),
487 : stream->url, strlen( stream->url ),
488 : &stream->end, sizeof( stream->end ),
489 : &stream->lastmodified, sizeof( stream->lastmodified ),
490 : &seekable, sizeof( seekable ),
491 0 : NULL );
492 :
493 0 : if( ! pMes )
494 0 : return NPERR_GENERIC_ERROR;
495 :
496 0 : aRet = GetNPError( pMes );
497 0 : uint16_t* pSType = (uint16_t*)pMes->GetBytes();
498 0 : *stype = *pSType;
499 :
500 0 : delete [] pSType;
501 0 : delete pMes;
502 0 : return aRet;
503 : }
504 :
505 0 : void UnxPluginComm::NPP_Print( NPP /*instance*/, NPPrint* /*platformPrint*/ )
506 : {
507 0 : }
508 :
509 0 : NPError UnxPluginComm::NPP_SetWindow( NPP instance, NPWindow* window )
510 : {
511 0 : NPError aRet = NPERR_GENERIC_ERROR;
512 0 : GET_INSTANCE_RET( aRet );
513 :
514 : MediatorMessage* pMes =
515 : Transact( eNPP_SetWindow,
516 : POST_INSTANCE(),
517 : window, sizeof( NPWindow ),
518 0 : NULL );
519 0 : if( ! pMes )
520 0 : return NPERR_GENERIC_ERROR;
521 :
522 0 : aRet = GetNPError( pMes );
523 0 : delete pMes;
524 0 : return aRet;
525 : }
526 :
527 0 : void UnxPluginComm::NPP_Shutdown()
528 : {
529 0 : Send( eNPP_Shutdown, NULL );
530 0 : }
531 :
532 0 : void UnxPluginComm::NPP_StreamAsFile( NPP instance, NPStream* stream, const char* fname )
533 : {
534 0 : GET_INSTANCE();
535 0 : sal_uInt32 nFileID = GetStreamID( stream );
536 0 : if( nFileID == PluginConnector::UnknownStreamID )
537 0 : return;
538 :
539 : Send( eNPP_StreamAsFile,
540 : POST_INSTANCE(),
541 : &nFileID, sizeof( nFileID ),
542 : fname, strlen( fname ),
543 0 : NULL );
544 : }
545 :
546 0 : void UnxPluginComm::NPP_URLNotify( NPP instance, const char* url, NPReason reason, void* notifyData )
547 : {
548 0 : GET_INSTANCE();
549 :
550 : Send( eNPP_URLNotify,
551 : POST_INSTANCE(),
552 : url, strlen( url ),
553 : &reason, sizeof( reason ),
554 : ¬ifyData, sizeof( void* ),
555 0 : NULL );
556 0 : }
557 :
558 0 : int32_t UnxPluginComm::NPP_Write( NPP instance, NPStream* stream, int32_t offset, int32_t len, void* buffer )
559 : {
560 0 : GET_INSTANCE_RET( -1 );
561 0 : sal_uInt32 nFileID = GetStreamID( stream );
562 0 : if( nFileID == PluginConnector::UnknownStreamID )
563 0 : return -1;
564 :
565 : MediatorMessage* pMes =
566 : Transact( eNPP_Write,
567 : POST_INSTANCE(),
568 : &nFileID, sizeof( nFileID ),
569 : &offset, sizeof( offset ),
570 : buffer, static_cast<size_t>(len),
571 0 : NULL );
572 0 : if( ! pMes )
573 0 : return 0;
574 :
575 0 : int32_t aRet = pMes->GetUINT32();
576 0 : delete pMes;
577 :
578 0 : return aRet;
579 : }
580 :
581 0 : int32_t UnxPluginComm::NPP_WriteReady( NPP instance, NPStream* stream )
582 : {
583 0 : GET_INSTANCE_RET( -1 );
584 0 : sal_uInt32 nFileID = GetStreamID( stream );
585 0 : if( nFileID == PluginConnector::UnknownStreamID )
586 0 : return -1;
587 :
588 : MediatorMessage* pMes =
589 : Transact( eNPP_WriteReady,
590 : POST_INSTANCE(),
591 : &nFileID, sizeof( nFileID ),
592 0 : NULL );
593 :
594 0 : if( ! pMes )
595 0 : return 0;
596 :
597 0 : int32_t aRet = pMes->GetUINT32();
598 0 : delete pMes;
599 :
600 0 : return aRet;
601 : }
602 :
603 0 : char* UnxPluginComm::NPP_GetMIMEDescription()
604 : {
605 : static char* pDesc = NULL;
606 : MediatorMessage* pMes =
607 : Transact( eNPP_GetMIMEDescription,
608 0 : NULL );
609 0 : if( ! pMes )
610 0 : return (char*)"";
611 :
612 0 : if( pDesc )
613 0 : delete [] pDesc;
614 0 : pDesc = pMes->GetString();
615 0 : delete pMes;
616 0 : return pDesc;
617 : }
618 :
619 0 : NPError UnxPluginComm::NPP_GetValue( NPP /*instance*/, NPPVariable /*variable*/, void* /*value*/ )
620 : {
621 0 : return 0;
622 : }
623 :
624 0 : NPError UnxPluginComm::NPP_SetValue( NPP /*instance*/, NPNVariable /*variable*/, void* /*value*/ )
625 : {
626 0 : return 0;
627 0 : }
628 :
629 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|