blob: 25882dd4996e2d05fba4d37e2190457fe0a4b66c [file] [log] [blame]
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML>
<head>
<META HTTP-EQUIV="CONTENT-TYPE" CONTENT="text/html; charset=iso-8859-1">
<TITLE>Plugins for VCL</TITLE>
<META NAME="GENERATOR" CONTENT="StarOffice 7 (Linux)">
<META NAME="AUTHOR" CONTENT="Philipp Lohmann">
<META NAME="CREATED" CONTENT="20040128;13243100">
<META NAME="CHANGEDBY" CONTENT="Philipp Lohmann">
<META NAME="CHANGED" CONTENT="20040128;15341300">
<STYLE>
<!--
@page { size: 8.27in 11.69in }
P.western { font-family: "Helvetica", sans-serif; so-language: en-US }
-->
</STYLE>
</head>
<body LANG="de-DE" DIR="LTR">
<H1 LANG="en-US">Plugins for VCL</H1>
<P LANG="en-US" CLASS="western"><B>Project Owner:</B> <A HREF="mailto:pl@openoffice.org">Philipp
Lohmann</A>, last change: 2004/01/28</P>
<P LANG="en-US" CLASS="western" STYLE="margin-bottom: 0in"><BR>
</P>
<P LANG="en-US" CLASS="western">Currently only available for Unix
platforms: plugins move the whole platform dependent part of
VCL(Unix) into an own library. At runtime OOo decides what plugin
would suit the current desktop environment best; e.g. it uses a gtk
based plugin on GNOME desktops or a generic (plain Xlib based) plugin
on CDE. The foundation for this the pure abstraction of all Sal
interfaces (Sal: System Abstraction Layer &ndash; the name is sadly
coincidental with the sal project; the Sal layer in vcl existed first
historically).</P>
<H2 LANG="en-US">Why plugins ?</H2>
<P LANG="en-US" CLASS="western">For better system integration it is
necessary to run the system's toolkit inside the OOo process space.
E.g. to use toolkit themes for drawing controls it is imperative to
be able to ask the native toolkit to draw OOo's controls. Also
toolkits know how to access system features like recent document
lists, file dialogues, etc..</P>
<H2 LANG="en-US">What are the basics for writing a VCL(Unix) plugin ?</H2>
<P LANG="en-US" CLASS="western">The starting point for a new VCL
plugin is SalInstance. This is a factory interface the implementation
of which produces instances of all other Sal interfaces. At startup
the independent part of vcl tries to determine the correct plugin
(desktop autodetection) and then tries to load that library and ask
it for a SalInstance object. Every other Sal interface implentation
is produced via the corresponding method of SalInstance (see
vcl/inc/salinst.hxx for details).</P>
<H3>SalInstance</H3>
<P LANG="en-US" CLASS="western">The first step is to create an <CODE><FONT FACE="Courier, monospace">extern
&quot;C&quot;</FONT></CODE> function named create_SalInstance which
returns the SalInstance of your plugin. For many plugins it is
advantageous to inherit their SalInstance from the SalInstance of the
generic implementation so the new plugin can reuse the generic
implementation where appropriate; good examples for implementations
that can be inherited are SalSound, SalBitmap, SalGraphics and
SalPrinter. Especially SalGraphics should be used from the generic
implementation as it contains really difficult stuff like drawing
text with complex text layout (CTL) that would be a real pain to
implement with little gain since the result should still look like
the result of the generic SalGraphics. Still, if you want to
implement every Sal interface on your own there is of course nothing
to stop you from doing that.</P>
<P LANG="en-US" CLASS="western">SalInstance is also responsible for
the application main loop and the SolarMutex (the mutex vcl gets its
thread awareness from). Since toolkits tend to be nonfunctional
without their own main loop, this is the first feature you should
implement. The methods GetYieldMutex, ReleaseYieldMutex and
AcquireYieldMutex must return a vos::IMutex interface (see
vos/inc/vos/mutex.hxx) that synchronizes to the mutex of your special
toolkit. Then Yield must be implemented. Yield is VCL's interface to
the system main loop; when called it should look for all kinds of
events (e.g. X events) and dispatch them appropriately. If called
with parameter bWait set to TRUE it should wait until an event is
available and then dispatch it. If bWait is FALSE Yield should
dispatch all events already available and then return immediately.</P>
<P LANG="en-US" CLASS="western">Please note that this may be far from
trivial to implement depending on your toolkit since so much depends
on the main loop. Unless you implement every Sal interface yourself
it is basically necessary to inherit from the SalDisplay, SalXLib and
SalData classes of the generic implementation since these lay the
groundwork for most other generic implementations (X11SalFrame,
X11SalTimer, etc.). E.g. SalData adds file descriptors to be watched
for events in the main loop. To make this feasible the corresponding
methods on the SalXLib, SalData and SalDisplay are virtual so a new
implementation can overload these and still use the generic
implementation.</P>
<H3>SalFrame</H3>
<P LANG="en-US" CLASS="western">The next step is most likely
implementing the SalFrame interface. This is necessary for the
following reasons:</P>
<UL>
<LI><P LANG="en-US" CLASS="western">If you want to use any window
inside your toolkit you most likely need a parent that already is a
such a toolkit window; e.g. if you want to have native file
dialogues you'll want to have a document window as their &ldquo;parent&rdquo;(or
rather make the dialogue window make transient for the document
window in X speak).</P>
<LI><P LANG="en-US" CLASS="western">SalFrame reads the native system
settings, so if you want to have OOo's UI using the correct colors
and fonts you'll need to implement at least the UpdateSettings
method.</P>
</UL>
<P LANG="en-US" CLASS="western">When implementing SalFrame you must
overcome the following problems:</P>
<UL>
<LI><P LANG="en-US" CLASS="western">SalFrame produces a SalGraphics;
here you most likely want to inherit from the generic
implementation. The X11SalGraphics for a frame needs to be
initialized with a native X drawable, so you need to get the Xlib
Window from your native top-level widget. You also need the Xlib
Window to implement the GetSystemData method.</P>
<LI><P LANG="en-US" CLASS="western">SalFrame needs to process
internationalized input; there is most likely an abstraction inside
your toolkit you'll want to use, so be prepared to send VCL's
abstracted input method (IM) events instead of simple key events.</P>
<LI><P LANG="en-US" CLASS="western">SalFrame can be constructed as a
child window of a native window (this is used e.g. in the SDK's java
bean where you plug OOo into another application). You'll need to
find an appropriate widget to do that with your toolkit (e.g. like a
GtkPlug in gtk).</P>
<LI><P LANG="en-US" CLASS="western">You must prevent you frame
widget from drawing its own background as this would interfere with
VCL's controls which draw themselves directly onto the window
without being known to your toolkit.</P>
</UL>
<H3>SalObjects</H3>
<P LANG="en-US" CLASS="western">If you have implemented SalFrame,
you'll need to implement SalObject, too. SalObject is a child window
of a SalFrame guaranteed to be a native system window (that is in
Xtoolkit terms a widget rather than a gadget). This is needed for
plugins and java applets inside documents. There are only two
obstacles doing this as SalObject is really rather boring:</P>
<UL>
<LI><P LANG="en-US" CLASS="western">You need to find an appropriate
widget (a drawing area will generally do)</P>
<LI><P LANG="en-US" CLASS="western">Since the SalObject is embedded
into a lot of gadgets (which is what VCL's controls are from a
toolkit standpoint), a real widget will overlap them if any geometry
is shared. This would e.g. lead to a plugin drawing over OOo's
toolbars if you scroll the corresponding document down slowly. To
avoid this SalObject windows need to be shaped using the X SHAPE
extension.</P>
</UL>
<H2>General considerations</H2>
<P LANG="en-US" CLASS="western">While implementing your own plugin
you may find it necessary to change something inside the generic
plugin. Please do so if it suits you, but contact one of the vcl team
(e.g. The author of this document) to check whether your change does
not break anything for other implementations.</P>
<P LANG="en-US" CLASS="western">In general it may be a good idea to
contact the vcl developers before and during the implementation on
the <A HREF="mailto:dev@gsl.openoffice.org">dev@gsl.openoffice.org</A>
mailinglist as all kinds of questions may arise (especially
considering that VCL is largely undocumented code up today).</P>
</body>
</HTML>