2006-04-27 22:40:28 +04:00
|
|
|
/*
|
2015-11-13 13:37:15 +03:00
|
|
|
* Copyright 2002-2015, Haiku, Inc. All Rights Reserved.
|
2006-04-27 22:40:28 +04:00
|
|
|
* Distributed under the terms of the MIT License.
|
|
|
|
*/
|
2002-07-09 16:24:59 +04:00
|
|
|
#ifndef _TRANSLATOR_ROSTER_H
|
|
|
|
#define _TRANSLATOR_ROSTER_H
|
|
|
|
|
2009-08-27 18:20:56 +04:00
|
|
|
|
2002-07-09 16:24:59 +04:00
|
|
|
#include <Archivable.h>
|
|
|
|
#include <TranslationDefs.h>
|
|
|
|
|
2009-05-26 03:51:16 +04:00
|
|
|
|
2002-07-09 16:24:59 +04:00
|
|
|
struct translation_format;
|
|
|
|
|
|
|
|
class BBitmap;
|
2007-10-16 00:13:55 +04:00
|
|
|
class BMessage;
|
|
|
|
class BMessenger;
|
2002-07-09 16:24:59 +04:00
|
|
|
class BPositionIO;
|
|
|
|
class BQuery;
|
2007-10-16 00:13:55 +04:00
|
|
|
class BRect;
|
|
|
|
class BTranslator;
|
|
|
|
class BView;
|
|
|
|
struct entry_ref;
|
2002-07-09 16:24:59 +04:00
|
|
|
|
|
|
|
|
Make sure images containing BTranslators are not unloaded early
When a translator is uninstalled, BTranslatorPrivate::_RemoveTranslators is
called. This method used to unload the image containing the translator after
calling Release() on it resulting in several problems:
- If the translator was still busy, e.g. translating something while being
installed, it crashed since the image was unloaded even though its refcount
was larger than 0.
- Applications using code from one of the translators (e.g. its config view)
would crash when the translator is uninstalled (this is bug #12005).
This problem is now fixed. The roster keeps track of all translators whose
image it manages (even if the translator was already removed from the roster).
It also keeps a refcount to all images. When a translator's refcount drops to
zero and it belonged to a roster at some point, it does not delete itself, but
notifies the roster that it is ready to destruct, which then removes it from
the roster if the translator is still in it, destroys the translator, decrements
the refcount of the image and if the new refcount is zero, unloads the image.
All of this is done in a message handler, since if the translator called
TranslatorDeleted like before, the unloaded image would be referenced when
the stack is walked up.
Finally, the DataTranslations preflet is required to Acquire() the translator
whose config view it is showing, because otherwise its refcount could be reduced
to 0 and the image unloaded. BTranslatorRoster now enables users to acquire a
translator by ID. By the time the translator has to be released, it might not
be part of the roster anymore though. Since BTranslatorRoster tries not to give
out raw pointers to the translators it manages, users who acquire a translator
through a roster now are given a BTranslatorReleaseDelegate, which allows for
releasing the BTranslator exactly once and then self-destructs.
Signed-off-by: Axel Dörfler <axeld@pinc-software.de>
2015-11-08 18:16:05 +03:00
|
|
|
class BTranslatorReleaseDelegate {
|
|
|
|
public:
|
|
|
|
BTranslatorReleaseDelegate(BTranslator* translator);
|
|
|
|
|
|
|
|
void Release();
|
|
|
|
|
|
|
|
private:
|
|
|
|
BTranslator* fUnderlying;
|
|
|
|
};
|
|
|
|
|
|
|
|
|
2002-07-09 16:24:59 +04:00
|
|
|
class BTranslatorRoster : public BArchivable {
|
2009-05-26 03:51:16 +04:00
|
|
|
public:
|
|
|
|
BTranslatorRoster();
|
|
|
|
BTranslatorRoster(BMessage* model);
|
|
|
|
virtual ~BTranslatorRoster();
|
|
|
|
|
|
|
|
static BTranslatorRoster* Default();
|
|
|
|
|
|
|
|
virtual status_t Archive(BMessage* into, bool deep = true) const;
|
|
|
|
static BArchivable* Instantiate(BMessage* from);
|
|
|
|
|
|
|
|
status_t AddTranslators(const char* loadPath = NULL);
|
|
|
|
status_t AddTranslator(BTranslator* translator);
|
|
|
|
|
|
|
|
virtual status_t Identify(BPositionIO* source,
|
|
|
|
BMessage* ioExtension,
|
|
|
|
translator_info* _info, uint32 hintType = 0,
|
|
|
|
const char* hintMIME = NULL,
|
|
|
|
uint32 wantType = 0);
|
|
|
|
|
|
|
|
virtual status_t GetTranslators(BPositionIO* source,
|
|
|
|
BMessage* ioExtension,
|
|
|
|
translator_info** _info, int32* _numInfo,
|
|
|
|
uint32 hintType = 0,
|
|
|
|
const char* hintMIME = NULL,
|
|
|
|
uint32 wantType = 0);
|
|
|
|
|
|
|
|
virtual status_t GetAllTranslators(translator_id** _list,
|
|
|
|
int32* _count);
|
|
|
|
|
|
|
|
virtual status_t GetTranslatorInfo(translator_id translatorID,
|
|
|
|
const char** _name, const char** _info,
|
|
|
|
int32* _version);
|
|
|
|
|
|
|
|
virtual status_t GetInputFormats(translator_id translatorID,
|
|
|
|
const translation_format** _formats,
|
|
|
|
int32* _numFormats);
|
|
|
|
|
|
|
|
virtual status_t GetOutputFormats(translator_id translatorID,
|
|
|
|
const translation_format** _formats,
|
|
|
|
int32* _numFormats);
|
|
|
|
|
|
|
|
virtual status_t Translate(BPositionIO* source,
|
|
|
|
const translator_info* info,
|
|
|
|
BMessage* ioExtension,
|
|
|
|
BPositionIO* destination,
|
|
|
|
uint32 wantOutType, uint32 hintType = 0,
|
|
|
|
const char* hintMIME = NULL);
|
|
|
|
|
|
|
|
virtual status_t Translate(translator_id translatorID,
|
|
|
|
BPositionIO* source, BMessage* ioExtension,
|
|
|
|
BPositionIO* destination,
|
|
|
|
uint32 wantOutType);
|
|
|
|
|
|
|
|
virtual status_t MakeConfigurationView(
|
|
|
|
translator_id translatorID,
|
|
|
|
BMessage* ioExtension, BView** _view,
|
|
|
|
BRect* _extent);
|
|
|
|
|
|
|
|
virtual status_t GetConfigurationMessage(
|
|
|
|
translator_id translatorID,
|
|
|
|
BMessage* ioExtension);
|
|
|
|
|
Make sure images containing BTranslators are not unloaded early
When a translator is uninstalled, BTranslatorPrivate::_RemoveTranslators is
called. This method used to unload the image containing the translator after
calling Release() on it resulting in several problems:
- If the translator was still busy, e.g. translating something while being
installed, it crashed since the image was unloaded even though its refcount
was larger than 0.
- Applications using code from one of the translators (e.g. its config view)
would crash when the translator is uninstalled (this is bug #12005).
This problem is now fixed. The roster keeps track of all translators whose
image it manages (even if the translator was already removed from the roster).
It also keeps a refcount to all images. When a translator's refcount drops to
zero and it belonged to a roster at some point, it does not delete itself, but
notifies the roster that it is ready to destruct, which then removes it from
the roster if the translator is still in it, destroys the translator, decrements
the refcount of the image and if the new refcount is zero, unloads the image.
All of this is done in a message handler, since if the translator called
TranslatorDeleted like before, the unloaded image would be referenced when
the stack is walked up.
Finally, the DataTranslations preflet is required to Acquire() the translator
whose config view it is showing, because otherwise its refcount could be reduced
to 0 and the image unloaded. BTranslatorRoster now enables users to acquire a
translator by ID. By the time the translator has to be released, it might not
be part of the roster anymore though. Since BTranslatorRoster tries not to give
out raw pointers to the translators it manages, users who acquire a translator
through a roster now are given a BTranslatorReleaseDelegate, which allows for
releasing the BTranslator exactly once and then self-destructs.
Signed-off-by: Axel Dörfler <axeld@pinc-software.de>
2015-11-08 18:16:05 +03:00
|
|
|
BTranslatorReleaseDelegate* AcquireTranslator(int32 translatorID);
|
|
|
|
|
2009-05-26 03:51:16 +04:00
|
|
|
status_t GetRefFor(translator_id translatorID,
|
|
|
|
entry_ref* ref);
|
|
|
|
bool IsTranslator(entry_ref* ref);
|
|
|
|
|
|
|
|
status_t StartWatching(BMessenger target);
|
|
|
|
status_t StopWatching(BMessenger target);
|
|
|
|
|
|
|
|
class Private;
|
|
|
|
|
|
|
|
private:
|
|
|
|
// unimplemented
|
|
|
|
BTranslatorRoster(
|
|
|
|
const BTranslatorRoster& other);
|
|
|
|
BTranslatorRoster& operator=(const BTranslatorRoster& other);
|
|
|
|
|
|
|
|
virtual void ReservedTranslatorRoster1();
|
|
|
|
virtual void ReservedTranslatorRoster2();
|
|
|
|
virtual void ReservedTranslatorRoster3();
|
|
|
|
virtual void ReservedTranslatorRoster4();
|
|
|
|
virtual void ReservedTranslatorRoster5();
|
|
|
|
virtual void ReservedTranslatorRoster6();
|
|
|
|
|
|
|
|
void _Initialize();
|
|
|
|
|
|
|
|
static const char* Version(int32* outCurVersion,
|
|
|
|
int32* outMinVersion,
|
|
|
|
int32 inAppVersion);
|
2009-05-26 03:32:53 +04:00
|
|
|
// for backward compatiblity only
|
|
|
|
|
2009-05-26 03:51:16 +04:00
|
|
|
private:
|
|
|
|
friend class Private;
|
2006-04-27 22:40:28 +04:00
|
|
|
|
2009-05-26 03:51:16 +04:00
|
|
|
Private* fPrivate;
|
|
|
|
int32 fUnused[6];
|
2006-04-27 22:40:28 +04:00
|
|
|
|
2009-05-26 03:51:16 +04:00
|
|
|
static BTranslatorRoster* sDefaultRoster;
|
2002-07-09 16:24:59 +04:00
|
|
|
};
|
|
|
|
|
2009-08-27 18:20:56 +04:00
|
|
|
|
|
|
|
#endif // _TRANSLATOR_ROSTER_H
|