summaryrefslogtreecommitdiffstats
path: root/xparts
diff options
context:
space:
mode:
Diffstat (limited to 'xparts')
-rw-r--r--xparts/AUTHORS3
-rw-r--r--xparts/COPYING340
-rw-r--r--xparts/Makefile.am7
-rw-r--r--xparts/README26
-rw-r--r--xparts/TODO11
-rw-r--r--xparts/configure.in.in1
-rw-r--r--xparts/doc/gtkxpart.fig55
-rw-r--r--xparts/doc/gtkxpart.pngbin0 -> 5917 bytes
-rw-r--r--xparts/doc/kparts.fig71
-rw-r--r--xparts/doc/kparts.pngbin0 -> 5916 bytes
-rw-r--r--xparts/doc/kxpart.fig55
-rw-r--r--xparts/doc/kxpart.pngbin0 -> 6749 bytes
-rw-r--r--xparts/doc/kxparthost.fig15
-rw-r--r--xparts/doc/kxparthost.pngbin0 -> 1652 bytes
-rw-r--r--xparts/doc/xparts.fig48
-rw-r--r--xparts/doc/xparts.html293
-rw-r--r--xparts/doc/xparts.pngbin0 -> 4197 bytes
-rw-r--r--xparts/mozilla/Makefile.am25
-rw-r--r--xparts/mozilla/README2
-rw-r--r--xparts/mozilla/configure.in.in31
-rw-r--r--xparts/mozilla/kmozilla.c193
-rw-r--r--xparts/mozilla/kmozilla.desktop9
-rw-r--r--xparts/mozilla/kmozilla.h34
-rw-r--r--xparts/mozilla/kmozilla.rc11
-rw-r--r--xparts/mozilla/kmozilla_ext.c125
-rw-r--r--xparts/mozilla/kmozilla_ext.h41
-rw-r--r--xparts/mozilla/kmozillapart.cpp51
-rw-r--r--xparts/mozilla/kmozillapart.h27
-rw-r--r--xparts/mozilla/kshell.cpp76
-rw-r--r--xparts/mozilla/main.c69
-rw-r--r--xparts/mozilla/parthost.rc14
-rw-r--r--xparts/src/Makefile.am7
-rw-r--r--xparts/src/gtk/Makefile.am13
-rw-r--r--xparts/src/gtk/configure.in.in1
-rw-r--r--xparts/src/gtk/gtkbrowserextension.c244
-rw-r--r--xparts/src/gtk/gtkbrowserextension.h54
-rw-r--r--xparts/src/gtk/gtkpart.c299
-rw-r--r--xparts/src/gtk/gtkpart.h61
-rw-r--r--xparts/src/interfaces/Makefile.am3
-rw-r--r--xparts/src/interfaces/xbrowserextension.h17
-rw-r--r--xparts/src/interfaces/xbrowsersignals.h15
-rw-r--r--xparts/src/interfaces/xpart.h36
-rw-r--r--xparts/src/interfaces/xparthost.h53
-rw-r--r--xparts/src/interfaces/xpartmanager.h20
-rw-r--r--xparts/src/kde/Makefile.am17
-rw-r--r--xparts/src/kde/kbrowsersignals.cpp31
-rw-r--r--xparts/src/kde/kbrowsersignals.h27
-rw-r--r--xparts/src/kde/xparthost_kpart.cpp150
-rw-r--r--xparts/src/kde/xparthost_kpart.h74
-rw-r--r--xparts/xpart_notepad/Makefile.am29
-rw-r--r--xparts/xpart_notepad/README3
-rw-r--r--xparts/xpart_notepad/shell_xparthost.cpp80
-rw-r--r--xparts/xpart_notepad/shell_xparthost.h29
-rw-r--r--xparts/xpart_notepad/shell_xparthost.rc11
-rw-r--r--xparts/xpart_notepad/xp_notepad.cpp114
-rw-r--r--xparts/xpart_notepad/xp_notepad.desktop9
-rw-r--r--xparts/xpart_notepad/xp_notepad.rc11
-rw-r--r--xparts/xpart_notepad/xp_notepad_factory.cpp72
-rw-r--r--xparts/xpart_notepad/xp_notepad_factory.h62
59 files changed, 3175 insertions, 0 deletions
diff --git a/xparts/AUTHORS b/xparts/AUTHORS
new file mode 100644
index 00000000..2853eb2c
--- /dev/null
+++ b/xparts/AUTHORS
@@ -0,0 +1,3 @@
+Matthias Ettrich <ettrich@kde.org>
+Simon Hausmann <hausmann@kde.org>
+Lars Knoll <knoll@kde.org>
diff --git a/xparts/COPYING b/xparts/COPYING
new file mode 100644
index 00000000..d60c31a9
--- /dev/null
+++ b/xparts/COPYING
@@ -0,0 +1,340 @@
+ GNU GENERAL PUBLIC LICENSE
+ Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.
+ 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+ Preamble
+
+ The licenses for most software are designed to take away your
+freedom to share and change it. By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users. This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it. (Some other Free Software Foundation software is covered by
+the GNU Library General Public License instead.) You can apply it to
+your programs, too.
+
+ When we speak of free software, we are referring to freedom, not
+price. Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+ To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+ For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have. You must make sure that they, too, receive or can get the
+source code. And you must show them these terms so they know their
+rights.
+
+ We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+ Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software. If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+ Finally, any free program is threatened constantly by software
+patents. We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary. To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+ The precise terms and conditions for copying, distribution and
+modification follow.
+
+ GNU GENERAL PUBLIC LICENSE
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+ 0. This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License. The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language. (Hereinafter, translation is included without limitation in
+the term "modification".) Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope. The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+ 1. You may copy and distribute verbatim copies of the Program's
+source code as you receive it, in any medium, provided that you
+conspicuously and appropriately publish on each copy an appropriate
+copyright notice and disclaimer of warranty; keep intact all the
+notices that refer to this License and to the absence of any warranty;
+and give any other recipients of the Program a copy of this License
+along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
+
+ 2. You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+ a) You must cause the modified files to carry prominent notices
+ stating that you changed the files and the date of any change.
+
+ b) You must cause any work that you distribute or publish, that in
+ whole or in part contains or is derived from the Program or any
+ part thereof, to be licensed as a whole at no charge to all third
+ parties under the terms of this License.
+
+ c) If the modified program normally reads commands interactively
+ when run, you must cause it, when started running for such
+ interactive use in the most ordinary way, to print or display an
+ announcement including an appropriate copyright notice and a
+ notice that there is no warranty (or else, saying that you provide
+ a warranty) and that users may redistribute the program under
+ these conditions, and telling the user how to view a copy of this
+ License. (Exception: if the Program itself is interactive but
+ does not normally print such an announcement, your work based on
+ the Program is not required to print an announcement.)
+
+These requirements apply to the modified work as a whole. If
+identifiable sections of that work are not derived from the Program,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works. But when you
+distribute the same sections as part of a whole which is a work based
+on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+ 3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+ a) Accompany it with the complete corresponding machine-readable
+ source code, which must be distributed under the terms of Sections
+ 1 and 2 above on a medium customarily used for software interchange; or,
+
+ b) Accompany it with a written offer, valid for at least three
+ years, to give any third party, for a charge no more than your
+ cost of physically performing source distribution, a complete
+ machine-readable copy of the corresponding source code, to be
+ distributed under the terms of Sections 1 and 2 above on a medium
+ customarily used for software interchange; or,
+
+ c) Accompany it with the information you received as to the offer
+ to distribute corresponding source code. (This alternative is
+ allowed only for noncommercial distribution and only if you
+ received the program in object code or executable form with such
+ an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for
+making modifications to it. For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to
+control compilation and installation of the executable. However, as a
+special exception, the source code distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering
+access to copy from a designated place, then offering equivalent
+access to copy the source code from the same place counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+ 4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License. Any attempt
+otherwise to copy, modify, sublicense or distribute the Program is
+void, and will automatically terminate your rights under this License.
+However, parties who have received copies, or rights, from you under
+this License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+ 5. You are not required to accept this License, since you have not
+signed it. However, nothing else grants you permission to modify or
+distribute the Program or its derivative works. These actions are
+prohibited by law if you do not accept this License. Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+ 6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program subject to
+these terms and conditions. You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+ 7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Program at all. For example, if a patent
+license would not permit royalty-free redistribution of the Program by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system, which is
+implemented by public license practices. Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+ 8. If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded. In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+ 9. The Free Software Foundation may publish revised and/or new versions
+of the General Public License from time to time. Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+Each version is given a distinguishing version number. If the Program
+specifies a version number of this License which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation. If the Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+ 10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission. For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this. Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+ NO WARRANTY
+
+ 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+ 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+
+ END OF TERMS AND CONDITIONS
+
+ How to Apply These Terms to Your New Programs
+
+ If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+ To do so, attach the following notices to the program. It is safest
+to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+ <one line to give the program's name and a brief idea of what it does.>
+ Copyright (C) <year> <name of author>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+
+Also add information on how to contact you by electronic and paper mail.
+
+If the program is interactive, make it output a short notice like this
+when it starts in an interactive mode:
+
+ Gnomovision version 69, Copyright (C) year name of author
+ Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+ This is free software, and you are welcome to redistribute it
+ under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License. Of course, the commands you use may
+be called something other than `show w' and `show c'; they could even be
+mouse-clicks or menu items--whatever suits your program.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the program, if
+necessary. Here is a sample; alter the names:
+
+ Yoyodyne, Inc., hereby disclaims all copyright interest in the program
+ `Gnomovision' (which makes passes at compilers) written by James Hacker.
+
+ <signature of Ty Coon>, 1 April 1989
+ Ty Coon, President of Vice
+
+This General Public License does not permit incorporating your program into
+proprietary programs. If your program is a subroutine library, you may
+consider it more useful to permit linking proprietary applications with the
+library. If this is what you want to do, use the GNU Library General
+Public License instead of this License.
diff --git a/xparts/Makefile.am b/xparts/Makefile.am
new file mode 100644
index 00000000..85bec8cd
--- /dev/null
+++ b/xparts/Makefile.am
@@ -0,0 +1,7 @@
+
+SUBDIRS = src xpart_notepad
+
+EXTRA_DIST = Makefile.cvs glib.m4 gtk.m4
+
+dist-hook:
+ cd $(top_distdir) && perl $(top_srcdir)/am_edit
diff --git a/xparts/README b/xparts/README
new file mode 100644
index 00000000..c9b091d0
--- /dev/null
+++ b/xparts/README
@@ -0,0 +1,26 @@
+
+You will find here the XPart technology, as implemented by Simon Haussman,
+Mathias Ettrich and Lars Knoll. Basically, XPart allows out of process
+embedding. For more information, see:
+http://trolls.troll.no/~lars/xparts/doc/xparts.html
+
+Currently XPart is more a proof of concept than a stabilized and maintained
+technology. The only application using it is kmozilla, which makes the
+Gecko html/browser (the one of mozilla) available as a kpart.
+
+The technology is not used enough to guarantee that the current state is the
+best, so it might develop it further. Understand by that, that
+_binary compatibility might not be kept between releases_ .
+
+But don't be afraid by that. XPart is a very promising technology and the api
+looks good for the moment. We do not plan any change.
+
+If you are developing something with XPart, please make yourself known to the
+kde development mailing lists, so that we can help you and get feedback. I'm
+working on a xpart notepad to show how to develop a xpart editor component.
+This editor will be committed after the 2.1 release though. I am also working
+on making vim available as a xpart/kpart component.
+
+ Philippe Fremy <pfremy@chez.com>
+
+
diff --git a/xparts/TODO b/xparts/TODO
new file mode 100644
index 00000000..dc7473ca
--- /dev/null
+++ b/xparts/TODO
@@ -0,0 +1,11 @@
+KPart::queryInterface?
+
+Interfaces in GTK???
+eindeutiger DCOP name fuer Interfaces
+
+XPartHost:
+started neuen manager und pollt.
+
+XPartManager
+
+KWin: Smart transient handling
diff --git a/xparts/configure.in.in b/xparts/configure.in.in
new file mode 100644
index 00000000..284c0cf5
--- /dev/null
+++ b/xparts/configure.in.in
@@ -0,0 +1 @@
+DO_NOT_COMPILE="$DO_NOT_COMPILE xparts"
diff --git a/xparts/doc/gtkxpart.fig b/xparts/doc/gtkxpart.fig
new file mode 100644
index 00000000..fc0669bd
--- /dev/null
+++ b/xparts/doc/gtkxpart.fig
@@ -0,0 +1,55 @@
+#FIG 3.2
+Landscape
+Center
+Metric
+A4
+100.00
+Single
+-2
+1200 2
+2 2 0 1 0 7 100 0 -1 0.000 0 0 -1 0 0 5
+ 10125 2025 13050 2025 13050 3600 10125 3600 10125 2025
+2 4 0 1 0 7 100 0 20 0.000 0 0 19 0 0 5
+ 13500 3375 13500 2700 11925 2700 11925 3375 13500 3375
+2 2 0 1 0 7 100 0 -1 0.000 0 0 -1 0 0 5
+ 10125 4950 13050 4950 13050 6525 10125 6525 10125 4950
+2 4 0 1 0 7 100 0 20 0.000 0 0 19 0 0 5
+ 13500 6300 13500 5625 11475 5625 11475 6300 13500 6300
+2 1 0 4 0 7 100 0 20 0.000 0 0 -1 1 1 2
+ 1 1 2.00 120.00 120.00
+ 1 1 2.00 120.00 120.00
+ 12825 5625 12825 3375
+2 1 0 2 0 7 100 0 -1 0.000 0 0 19 1 0 2
+ 1 1 1.00 60.00 120.00
+ 10800 6525 10350 7875
+2 2 0 1 0 7 100 0 -1 0.000 0 0 19 0 0 5
+ 9225 7875 11700 7875 11700 9900 9225 9900 9225 7875
+2 2 0 1 0 7 100 0 -1 0.000 0 0 -1 0 0 5
+ 9450 9000 11025 9000 11025 9675 9450 9675 9450 9000
+2 4 0 1 0 7 100 0 20 0.000 0 0 19 0 0 5
+ 12375 8775 12375 8100 10800 8100 10800 8775 12375 8775
+2 2 0 1 0 7 100 0 -1 0.000 0 0 -1 0 0 5
+ 9225 11250 10350 11250 10350 11925 9225 11925 9225 11250
+2 1 0 2 0 7 100 0 -1 0.000 0 0 19 1 0 2
+ 1 1 1.00 60.00 120.00
+ 9900 9675 9675 11250
+2 1 1 2 0 7 100 0 -1 4.500 0 0 -1 1 0 2
+ 1 1 1.00 60.00 120.00
+ 10350 9675 10350 11025
+2 2 1 1 0 7 100 0 -1 4.000 0 0 -1 0 0 5
+ 9000 11025 11700 11025 11700 12150 9000 12150 9000 11025
+2 4 0 1 0 7 100 0 20 0.000 0 0 19 0 0 5
+ 13050 9675 13050 9000 11250 9000 11250 9675 13050 9675
+4 0 0 100 0 0 12 0.0000 4 135 825 12375 3150 XPartHost\001
+4 0 0 100 0 0 12 0.0000 4 180 2040 10350 2475 KXPartHost : public KPart\001
+4 0 0 100 0 0 12 0.0000 4 180 1125 12150 6075 XPartManager\001
+4 0 0 100 0 0 12 0.0000 4 135 1680 13050 4275 DCOP communication\001
+4 0 0 100 0 0 12 0.0000 4 105 480 9900 7425 create\001
+4 0 0 100 0 0 12 0.0000 4 135 735 9450 8550 GtkXPart\001
+4 0 0 100 0 0 12 0.0000 4 180 1410 10350 5400 GtkXPartManager\001
+4 0 0 100 0 0 12 0.0000 4 135 1155 9675 9450 GtkMozEmbed\001
+4 0 0 100 0 0 12 0.0000 4 135 450 11250 8550 XPart\001
+4 0 0 100 0 0 12 0.0000 4 135 570 9450 11700 Mozilla\001
+4 0 0 100 0 0 12 0.0000 4 105 480 9225 10575 create\001
+4 0 0 100 0 16 12 0.0000 4 180 1560 10575 10575 load shared object\001
+4 0 0 100 0 0 12 0.0000 4 135 1410 11475 9450 BrowserExtension\001
diff --git a/xparts/doc/gtkxpart.png b/xparts/doc/gtkxpart.png
new file mode 100644
index 00000000..32e85e54
--- /dev/null
+++ b/xparts/doc/gtkxpart.png
Binary files differ
diff --git a/xparts/doc/kparts.fig b/xparts/doc/kparts.fig
new file mode 100644
index 00000000..afed114f
--- /dev/null
+++ b/xparts/doc/kparts.fig
@@ -0,0 +1,71 @@
+#FIG 3.2
+Landscape
+Center
+Metric
+A4
+100.00
+Single
+-2
+1200 2
+2 2 0 1 0 7 100 0 -1 0.000 0 0 -1 0 0 5
+ 1575 2025 2925 2025 2925 2700 1575 2700 1575 2025
+2 2 0 1 0 7 100 0 -1 0.000 0 0 -1 0 0 5
+ 2925 2025 4275 2025 4275 2700 2925 2700 2925 2025
+2 2 0 1 0 7 100 0 -1 0.000 0 0 -1 0 0 5
+ 1575 1350 4275 1350 4275 2700 1575 2700 1575 1350
+2 2 0 1 0 7 100 0 -1 0.000 0 0 -1 0 0 5
+ 7425 3150 8550 3150 8550 3825 7425 3825 7425 3150
+2 2 0 1 0 7 100 0 -1 0.000 0 0 -1 0 0 5
+ 6300 3150 7425 3150 7425 3825 6300 3825 6300 3150
+2 2 0 1 0 7 100 0 -1 0.000 0 0 -1 0 0 5
+ 6300 2475 8550 2475 8550 3150 6300 3150 6300 2475
+2 1 0 2 0 7 100 0 -1 0.000 0 0 -1 1 0 2
+ 1 1 1.00 60.00 120.00
+ 2250 2700 1800 4275
+2 2 0 1 0 7 100 0 -1 0.000 0 0 -1 0 0 5
+ 1125 4275 2475 4275 2475 4950 1125 4950 1125 4275
+2 2 0 1 0 7 100 0 -1 0.000 0 0 -1 0 0 5
+ 2700 4275 3600 4275 3600 4950 2700 4950 2700 4275
+2 2 0 1 0 7 100 0 -1 0.000 0 0 -1 0 0 5
+ 900 6075 2475 6075 2475 6750 900 6750 900 6075
+2 2 0 1 0 7 100 0 -1 0.000 0 0 -1 0 0 5
+ 2925 6075 4050 6075 4050 6750 2925 6750 2925 6075
+2 1 0 2 0 7 100 0 -1 0.000 0 0 19 1 0 2
+ 1 1 1.00 60.00 120.00
+ 1800 4950 1350 6075
+2 1 0 2 0 7 100 0 -1 0.000 0 0 -1 1 0 2
+ 1 1 1.00 60.00 120.00
+ 2025 4950 3600 6075
+2 1 0 2 0 7 100 0 -1 0.000 0 0 -1 1 0 2
+ 1 1 1.00 60.00 120.00
+ 2475 2700 3150 4275
+2 2 1 1 0 7 100 0 -1 4.000 0 0 -1 0 0 5
+ 675 4050 4275 4050 4275 6975 675 6975 675 4050
+2 1 1 2 0 7 100 0 -1 4.500 0 0 -1 1 0 2
+ 1 1 1.00 60.00 120.00
+ 3600 2700 3600 4050
+3 2 0 2 0 7 100 0 -1 0.000 0 1 0 3
+ 1 1 1.00 60.00 120.00
+ 6300 3600 5400 4050 4270 4243
+ 0.000 -1.000 0.000
+3 2 0 2 0 7 100 0 -1 0.000 0 1 0 3
+ 1 1 1.00 60.00 120.00
+ 4275 2025 5625 2250 6300 2700
+ 0.000 -1.000 0.000
+4 0 0 100 0 16 12 0.0000 4 135 1035 5175 4500 offer service\001
+4 0 0 100 0 0 12 0.0000 4 180 960 1800 2475 KLibFactory\001
+4 0 0 100 0 0 12 0.0000 4 135 900 3150 2475 KLibLoader\001
+4 0 0 100 0 16 12 0.0000 4 180 945 2475 1800 Application\001
+4 0 0 100 0 16 12 0.0000 4 180 1155 5400 2025 query service\001
+4 0 0 100 0 0 12 0.0000 4 180 750 7650 3600 KSyCoCa\001
+4 0 0 100 0 16 12 0.0000 4 135 660 6525 3600 KTrader\001
+4 0 0 100 0 16 12 0.0000 4 135 315 7200 2925 KIO\001
+4 0 0 100 0 0 12 0.0000 4 105 480 1575 3375 create\001
+4 0 0 100 0 16 12 0.0000 4 135 450 1575 4725 KPart\001
+4 0 0 100 0 0 12 0.0000 4 135 450 2925 4725 KPart\001
+4 0 0 100 0 0 12 0.0000 4 135 1410 900 6525 BrowserExtension\001
+4 0 0 100 0 0 12 0.0000 4 135 810 3150 6525 TextEditor\001
+4 0 0 100 0 0 12 0.0000 4 180 1110 1575 5850 queryInterface\001
+4 0 0 100 0 0 12 0.0000 4 180 1110 3150 5625 queryInterface\001
+4 0 0 100 0 0 12 0.0000 4 105 480 2475 3825 create\001
+4 0 0 100 0 16 12 0.0000 4 180 1560 3600 3375 load shared object\001
diff --git a/xparts/doc/kparts.png b/xparts/doc/kparts.png
new file mode 100644
index 00000000..b2d534b3
--- /dev/null
+++ b/xparts/doc/kparts.png
Binary files differ
diff --git a/xparts/doc/kxpart.fig b/xparts/doc/kxpart.fig
new file mode 100644
index 00000000..ce238956
--- /dev/null
+++ b/xparts/doc/kxpart.fig
@@ -0,0 +1,55 @@
+#FIG 3.2
+Landscape
+Center
+Metric
+A4
+100.00
+Single
+-2
+1200 2
+2 2 0 1 0 7 100 0 -1 0.000 0 0 -1 0 0 5
+ 10125 2025 13050 2025 13050 3600 10125 3600 10125 2025
+2 4 0 1 0 7 100 0 20 0.000 0 0 19 0 0 5
+ 13500 3375 13500 2700 11925 2700 11925 3375 13500 3375
+2 2 0 1 0 7 100 0 -1 0.000 0 0 -1 0 0 5
+ 10125 4950 13050 4950 13050 6525 10125 6525 10125 4950
+2 4 0 1 0 7 100 0 20 0.000 0 0 19 0 0 5
+ 13500 6300 13500 5625 11475 5625 11475 6300 13500 6300
+2 1 0 4 0 7 100 0 20 0.000 0 0 -1 1 1 2
+ 1 1 2.00 120.00 120.00
+ 1 1 2.00 120.00 120.00
+ 12825 5625 12825 3375
+2 1 0 2 0 7 100 0 20 0.000 0 0 -1 1 0 2
+ 1 1 1.00 60.00 120.00
+ 10575 7200 9225 10125
+2 2 0 1 0 7 100 0 -1 0.000 0 0 -1 0 0 5
+ 11475 6525 13050 6525 13050 7200 11475 7200 11475 6525
+2 1 1 2 0 7 100 0 -1 4.500 0 0 -1 1 0 2
+ 1 1 1.00 60.00 120.00
+ 12375 7200 12375 8550
+2 2 1 1 0 7 100 0 -1 4.000 0 0 -1 0 0 5
+ 7875 8550 13050 8550 13050 11475 7875 11475 7875 8550
+2 2 0 1 0 7 100 0 -1 0.000 0 0 19 0 0 5
+ 8325 9000 10800 9000 10800 11025 8325 11025 8325 9000
+2 4 0 1 0 7 100 0 20 0.000 0 0 19 0 0 5
+ 11925 9900 11925 9225 10350 9225 10350 9900 11925 9900
+2 2 0 1 0 7 100 0 -1 0.000 0 0 -1 0 0 5
+ 8550 10125 9675 10125 9675 10800 8550 10800 8550 10125
+2 2 0 1 0 7 100 0 -1 0.000 0 0 -1 0 0 5
+ 10125 6525 11475 6525 11475 7200 10125 7200 10125 6525
+2 1 0 2 0 7 100 0 -1 0.000 0 0 19 1 0 2
+ 1 1 1.00 60.00 120.00
+ 10086 6059 8775 9000
+4 0 0 100 0 0 12 0.0000 4 135 825 12375 3150 XPartHost\001
+4 0 0 100 0 0 12 0.0000 4 180 2040 10350 2475 KXPartHost : public KPart\001
+4 0 0 100 0 0 12 0.0000 4 180 1260 10350 5400 KXPartManager\001
+4 0 0 100 0 0 12 0.0000 4 180 1125 12150 6075 XPartManager\001
+4 0 0 100 0 0 12 0.0000 4 135 1680 13050 4275 DCOP communication\001
+4 0 0 100 0 0 12 0.0000 4 180 960 10350 6975 KLibFactory\001
+4 0 0 100 0 0 12 0.0000 4 135 900 11700 6975 KLibLoader\001
+4 0 0 100 0 16 12 0.0000 4 180 1560 12600 7875 load shared object\001
+4 0 0 100 0 0 12 0.0000 4 135 450 10800 9675 XPart\001
+4 0 0 100 0 0 12 0.0000 4 135 450 8775 10575 KPart\001
+4 0 0 100 0 0 12 0.0000 4 105 480 10350 7875 create\001
+4 0 0 100 0 0 12 0.0000 4 180 570 8550 9450 KXpart\001
+4 0 0 100 0 0 12 0.0000 4 105 480 8775 7650 create\001
diff --git a/xparts/doc/kxpart.png b/xparts/doc/kxpart.png
new file mode 100644
index 00000000..70ae2e5f
--- /dev/null
+++ b/xparts/doc/kxpart.png
Binary files differ
diff --git a/xparts/doc/kxparthost.fig b/xparts/doc/kxparthost.fig
new file mode 100644
index 00000000..fa34c141
--- /dev/null
+++ b/xparts/doc/kxparthost.fig
@@ -0,0 +1,15 @@
+#FIG 3.2
+Landscape
+Center
+Metric
+A4
+100.00
+Single
+-2
+1200 2
+2 2 0 1 0 7 100 0 -1 0.000 0 0 -1 0 0 5
+ 10125 2025 13050 2025 13050 3600 10125 3600 10125 2025
+2 4 0 1 0 7 100 0 20 0.000 0 0 19 0 0 5
+ 13500 3375 13500 2700 11925 2700 11925 3375 13500 3375
+4 0 0 100 0 0 12 0.0000 4 135 825 12375 3150 XPartHost\001
+4 0 0 100 0 0 12 0.0000 4 180 2040 10350 2475 KXPartHost : public KPart\001
diff --git a/xparts/doc/kxparthost.png b/xparts/doc/kxparthost.png
new file mode 100644
index 00000000..d223e687
--- /dev/null
+++ b/xparts/doc/kxparthost.png
Binary files differ
diff --git a/xparts/doc/xparts.fig b/xparts/doc/xparts.fig
new file mode 100644
index 00000000..6ac73ff2
--- /dev/null
+++ b/xparts/doc/xparts.fig
@@ -0,0 +1,48 @@
+#FIG 3.2
+Landscape
+Center
+Metric
+A4
+100.00
+Single
+-2
+1200 2
+2 4 0 1 0 7 100 0 20 0.000 0 0 19 0 0 5
+ 5175 4050 5175 3375 3600 3375 3600 4050 5175 4050
+2 4 0 1 0 7 100 0 20 0.000 0 0 19 0 0 5
+ 5400 5850 5400 5175 3600 5175 3600 5850 5400 5850
+2 4 0 1 0 7 100 0 20 0.000 0 0 19 0 0 5
+ 3600 8325 3600 7650 1800 7650 1800 8325 3600 8325
+2 4 0 1 0 7 100 0 20 0.000 0 0 19 0 0 5
+ 5850 8325 5850 7650 4050 7650 4050 8325 5850 8325
+2 1 0 2 0 7 100 0 20 0.000 0 0 -1 1 0 2
+ 1 1 1.00 60.00 120.00
+ 3375 6975 2925 7650
+2 1 0 2 0 7 100 0 20 0.000 0 0 -1 1 0 2
+ 1 1 1.00 60.00 120.00
+ 4050 6975 4950 7650
+2 4 0 1 0 7 100 0 20 0.000 0 0 19 0 0 5
+ 6750 6975 6750 6300 5175 6300 5175 6975 6750 6975
+2 1 0 2 0 7 100 0 20 0.000 0 0 -1 1 0 2
+ 1 1 1.00 60.00 120.00
+ 4725 5850 5850 6300
+2 1 0 2 0 7 100 0 20 0.000 0 0 -1 1 0 2
+ 1 1 1.00 60.00 120.00
+ 4275 5850 3825 6300
+2 4 0 1 0 7 100 0 20 0.000 0 0 19 0 0 5
+ 4500 6975 4500 6300 2925 6300 2925 6975 4500 6975
+2 1 0 4 0 7 100 0 20 0.000 0 0 -1 1 1 2
+ 1 1 2.00 120.00 120.00
+ 1 1 2.00 120.00 120.00
+ 4500 5175 4500 4050
+4 0 0 100 0 0 12 0.0000 4 135 825 4050 3825 XPartHost\001
+4 0 0 100 0 0 12 0.0000 4 180 1125 3825 5625 XPartManager\001
+4 0 0 100 0 0 12 0.0000 4 135 1410 2025 8100 BrowserExtension\001
+4 0 0 100 0 0 12 0.0000 4 135 810 4500 8100 TextEditor\001
+4 0 0 100 0 0 12 0.0000 4 135 450 5625 6750 XPart\001
+4 0 0 100 0 0 12 0.0000 4 135 450 3375 6750 XPart\001
+4 0 0 100 0 0 12 0.0000 4 105 480 5625 6075 create\001
+4 0 0 100 0 0 12 0.0000 4 180 1110 4725 7425 queryInterface\001
+4 0 0 100 0 0 12 0.0000 4 180 1110 1800 7425 queryInterface\001
+4 0 0 100 0 0 12 0.0000 4 135 1680 4725 4725 DCOP communication\001
+4 0 0 100 0 0 12 0.0000 4 105 480 3375 6075 create\001
diff --git a/xparts/doc/xparts.html b/xparts/doc/xparts.html
new file mode 100644
index 00000000..0ff872be
--- /dev/null
+++ b/xparts/doc/xparts.html
@@ -0,0 +1,293 @@
+<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
+<html>
+ <head>
+ <title>XParts - Extending KParts</title>
+ </head>
+
+ <body>
+<center>
+<h1>XParts - Extending KParts</h1>
+ <small>Matthias Ettrich, Simon Hausmann, Lars Knoll</small>
+</center>
+
+ <p>This article briefly describe the concepts, architecture and
+ reasoning behind the XParts technology. The purpose of XParts is
+ to extend KParts over language, toolkit, process and machine
+ bounderies. XParts makes it possible to write KDE components with
+ almost any toolkit or language an author prefers or to turn
+ existing applications into KDE components quite easily.
+
+ <p>In addition, XParts is also an important glueing technology to
+ make KParts available in other component based systems or to
+ utilize non-KPart components transparently as KParts.
+
+ <h4>Classic KParts</h4>
+
+ <p>In order to understand, what is extending about XParts, first a
+ brief overview on how KParts work.
+
+ <img src="kparts.png">
+
+ <p>Imagine an application - for example the integrated file manager
+ "Konqueror" - wants to utilize a component that handles the
+ "text/html" mimetype. It therefore asks the trader of the KIO
+ subsystem whether such a service is available and where. The
+ trader uses the system configuration cache to localize an
+ appropriate service that fits with the user's preferences. The
+ system configuration cache is a service type database
+ constructed from the desktop files of a KDE setup. In the case
+ of "text/html", the trader will very like return KDE's builtin
+ HTML viewer dubbed KHtml. This viewer is is most certainly
+ available as a KPart component. The application will then - via
+ KLibLoader and KLibFactory - load the shared library object that
+ implements the component and create a KPart instance. The
+ LibLoader keeps track of any objects created in the loaded
+ library and will automatically unload it after all objects have
+ been deleted.
+
+ <p>If the application does not only want to display HTML, but
+ act as a full featured browser, the plain KPart interface is not
+ sufficient. If the user clicks on a link, for example, the HTML
+ component has to request a new URL. This kind of interaction is
+ defined in the BrowserExtension interface. An application can
+ query the KParts for additonal interfaces and get handles to
+ them in case those are available. In the example case of KHtml,
+ the BrowserExtension interface is exported. In the case of a
+ text editor component, it's very likely that the TextEditor
+ interface is available.
+
+ <h4>In-process components</h4>
+
+ <p>The beauty of KParts is its simplicity. It's a clean and
+ flexible in-process approach with all its advantages:
+ <ul>
+ <li> lightweight - components share the same application
+ context and all its allocated resources.
+ <li> synchronious - calls are predictable, there are no
+ timeouts to wait for and no events to process in an uncertain
+ amount of time.
+ <li> stable - neither race conditions nor rare exceptions
+ can occur
+ <li> extremely powerful - there are virtually no
+ limitations to how a component API can look like (including
+ passing pointers) or what a plugin can do with an application.
+ </ul>
+
+ <p>Those advantages are unvaluable for a lightweight and tightly
+ integrated office suite like KOffice. However, there are no silver
+ bullets and most certainly there are drawbacks when the system is
+ used in settings with different requirements.
+
+ <p>Take the fourth item, it's comprehensive power while
+ maintaining simplicity. This was one of the main requirements of
+ the KOffice team, and it alone almost determines an in-process
+ approach with dynamically loadable shared objects. In a generic
+ browser like Konqueror, the requirements for integrated components
+ are not as high as with an office suite. In an office suite,
+ different components operate on one single document, whereas in a
+ browser, the components basically provide different views for
+ given Urls. To illustrate this issue, imagine how far the web
+ came with such primitive and inflexible component technology like
+ Netscape plugins. They did most of what people wanted to do with
+ browser plugins, though, and so became a huge success.
+
+ <h4>Out-of-process components</h4>
+
+ <p>To sum this up: for multi-view applications like a generic
+ browser, there's no technical argument why out-of-process
+ components could not be sufficient. So let's look closer at the
+ specific advantages of such a solution.
+
+ <ul>
+ <li>With out-of-process components, it's much easier to provide
+ applications as components that do not support being loaded
+ dynamically as shared library objects. Typical examples are
+ programs written in interpreted languages. With a pure in-process
+ model, one would have to be able to load the interpreter as
+ embedded language.
+
+ <li>If a component handles the event loop differently from the
+ embedding application, an complete event loop merger is
+ required. This glueing code can be tricky and might not work well
+ in all cases. It's much easier for out-of-process components to
+ provide full toolkit independence.
+
+ <li> components of the same type could share one process
+ context. Not sure where this is actually useful, but it has most
+ certainly some technical beauty attached to it.
+
+ </ul>
+
+ <p>Let's pick a concrete example. Imagine that you - for whatever
+ reason - want to offer the Mozilla rendering engine (gecko) as
+ KPart, so that users have an an alternative to KDE's builtin
+ rendering engine KHtml.
+
+ <p>The first step of such a project is to find out, whether
+ Mozilla already is available as a reusable component that could
+ form the basis of a KDE integration. And in fact, it is. A small
+ library called GtkMozEmbed makes it possible to load the entire
+ Mozilla as a single Gtk widget, i.e. the rendering engine gecko,
+ the networking protocol implementations, the javascript
+ interpreter and whatever else Mozilla.org comes up with. The
+ MozEmbed library works pretty similar to KParts. Once
+ instantiated, it dynamically loads all libraries required by
+ Mozilla. As an interesting side note, all Unix filemanager
+ projects that utilize Mozilla (for example the Nautilus
+ filemanager) use this library to embed mozilla. This means you are
+ in good company using a stock MozEmbed library, as you don't have
+ to maintain this code but somebody else will do it for you.
+
+ <p>Now that we have a dynamically loaded Gtk widget, how do we
+ turn that into a KPart? Quite straight forward. There is a
+ QGtkWidget extension available for Qt, that lets you use Gtk
+ widgets in your Qt applications. You simply create a QGtkWidget
+ with a pointer to the Gtk widget you get from MozEmbed and insert
+ that into your KPart. Then you do a few trivial reimplementations
+ of the virtual functions of the BrowserExtension interface that
+ map to the corresponding functions of Mozilla and you are
+ done. The result is a fully functional Konqueror that uses Mozilla
+ as backend - or rather a fully functional Mozilla that uses
+ Konqueror as graphical user interface, however you want to look at
+ it.
+
+ <h4>Trouble ahead</h4>
+
+ <p> While the skedged solution works, there are some unmentioned
+ and ugly details. First of all, Mozilla uses the event loop of
+ glib, while Konqueror uses Qt. Unfortunatly, mixing both event
+ loops is not possible with the current release of glib, unless one
+ want to end up with an application that constantly requires some
+ CPU to run, even when being idle. While this seems to be ok for
+ today's Java virtual machines, it's not acceptable by KDE's
+ quality standards. Until glib 2.0 is released, you need to patch
+ glib in order to make the QGtkWidget work properly. No big deal
+ for most Linux users, still a hassle. And keep in mind that glib
+ is a fairly open system. If the component was written in some
+ other toolkit, it might be possible that glueing code is
+ impossible to get right, without wasting at least a bit of CPU.
+
+ <p>The second problem is Mozilla's size. It's by no means an
+ ordinary component. In fact, it's a magnitude larger than the
+ Konqueror framework. And since Mozilla and Konqueror do not share
+ the same graphics toolkit, the toolkit's size has to be added to
+ that. It seems odd to load and unload such a huge amount of code -
+ and it can to lead to all kind of problems when trying to unload
+ it again.
+
+ <p>To make things worse, Mozilla wasn't even released as final
+ version yet. While it is already quite usable, it's stability is
+ still far from being production quality. This doesn't matter too
+ much for a standalone browser, but can really hurt with a
+ component. A standalone browser usually is supposed to display one
+ web page. If it crashes, this page is gone, so the user simply
+ tries again. With a generic browser like Konqueror, there is not
+ just one component active at a time, but several. There might be
+ some directory views, an embedded console, another toplevel window
+ window, an imaged preview and much more. A crashing Mozilla would
+ take all those component with it - and leave the user with only
+ half of its prior desktop.
+
+ <p>Imagine that some users define Mozilla to be the primary
+ component to handle text/html in Konqueror. After some testing, all
+ works well and they continue using it. A couple of days later, they
+ might have forgotten the configuration change they did. Whenever
+ they now hit a web page where Mozilla crashes, they will blame
+ Konqueror. This we don't want. No code is perfect, but if a crash
+ occurs in our code, at least it's our crash. That means, we can fix
+ it and we can provide newer versions.
+
+ <p>Thus, from a maintainance and support point of you, it is not
+ acceptable for KDE to run code inprocess that is not actually
+ maintained or controlled by the team, at least not in the default
+ setup.
+
+ <h4>Out-of-process components</h4>
+
+ <p>For the given reasons, it makes a lot of sense to extend KParts
+ over process bounderies. In addition, we also win a high degree of
+ toolkit and language independency.
+
+ <p>To make this work, we have to identify the streamable parts of
+ the KParts interface and offer them via some kind of middleware.
+
+ <p>We chose KDE's native desktop middleware, the desktop
+ communication protocol (DCOP) to establish the communication. In
+ addition to the fact that DCOP was explicitely designed for these
+ kind of tasks, there are some more benefits:
+ <ul>
+ <li> DCOP runs already on the desktop, i.e. there are no additonal costs
+ in terms of resource consumption.
+ <li> Does not put any limitations onto the interfaces as long as
+ data types are streamable
+ <li> Server architecture makes it easy and robust to detect
+ crashes on either side.
+ </ul>
+
+ There are several DCOP implementations available. The reference
+ implementation is the one using C++ and Qt that is used in KDE
+ applications. For Mozilla, we would choose a plain ANSI-C
+ implementation that uses glib.
+
+ <p>The following picture shows the interface structure:
+
+ <p> <img src="xparts.png">
+
+ <p>The main thing that differs from KParts is the
+ <em>XPartHost</em> interface that is responsible for embedding a
+ part. The missing link now is a standard KPart component that
+ implements the <em>XPartHost</em> interface. Via this
+ <b>KXPartHost</b> component, it is possible to use any XPart
+ transparently as KPart without changing a single line of code:
+ <p>
+ <img src="kxparthost.png">
+
+ <p>On the other side of the fence, we need an implementation of
+ the <em>XPartManager</em> interface and can serve us with
+ <em>XPart</em> interfaces. We provide this through the
+ relatively highlevel and generic classes GtkXPartManger and
+ GtkXPart, as shown in the next picture:
+ <p>
+ <img src="gtkxpart.png">
+ <p> The GtkXPart is a standard Gtk widget that can have a MozEmbed
+ widget as child widget. The only code that is necessary to write
+ is the code used to connect the <em>BrowserExtension</em>
+ interface to the corresponding functions of Mozilla.
+
+ <h4>External KParts</h4>
+
+ <p>The same technique can now be used to utilize standard KPart
+ components in an out-of-process fashion via the XPart system. All
+ we need is a KXPartManager that wraps standard KParts in
+ KXParts. The KXParts then export the <em>XPart</em> interface. The
+ complete structure is shown in the next picture:
+ <p><img src="kxpart.png">
+
+ <h4>Conclusion</h4> <p> Although the implementation of the
+ external mozilla part is more a proof of concept than a finished
+ xpart, we have shown a clean way to realize out of process
+ components on top of KParts. It could also be shown that this
+ approach is both language and toolkit independent.
+
+ <p>To accomplish this task, not a <em>single</em> line of code
+ in konqueror had to be changed. All we did was providing yet
+ another independent KPart component.
+
+ <p>By writing a small wrapper it is possible to embed any kind of
+ visual component. In addition, we can provide generic wrappers for
+ any kind of visual component model, as long as those models are
+ powerful enough to describe their interfaces and GUI requirements
+ at runtime. This includes KParts (eg. KOffice components), Bonobo
+ components (like the Nautilus MP3 viewer) and Uno components
+ provided by OpenOffice (formerly known as StarOffice).
+
+ <hr>
+ <address><a href="mailto:ettrich@kde.org">Matthias Ettrich</a></address>
+ <address><a href="mailto:hausmann@kde.org">Simon Hausmann</a></address>
+ <address><a href="mailto:knoll@kde.org">Lars Knoll</a></address>
+<!-- Created: Tue Oct 17 18:08:25 CEST 2000 -->
+<!-- hhmts start -->
+Last modified: Tue Apr 3 20:39:13 CEST 2001
+<!-- hhmts end -->
+ </body>
+</html>
diff --git a/xparts/doc/xparts.png b/xparts/doc/xparts.png
new file mode 100644
index 00000000..3193842a
--- /dev/null
+++ b/xparts/doc/xparts.png
Binary files differ
diff --git a/xparts/mozilla/Makefile.am b/xparts/mozilla/Makefile.am
new file mode 100644
index 00000000..1e499a2a
--- /dev/null
+++ b/xparts/mozilla/Makefile.am
@@ -0,0 +1,25 @@
+INCLUDES = -I$(srcdir)/../src/kde -I$(srcdir)/../src/interfaces -I$(srcdir)/../src/gtk -I$(prefix)/include -I$(top_srcdir) $(MOZILLA_INCLUDES) $(all_includes)
+
+AM_CFLAGS = $(GLIB_CFLAGS) $(GTK_CFLAGS)
+
+lib_LTLIBRARIES = libkmozillapart.la
+
+libkmozillapart_la_SOURCES = kmozillapart.cpp
+libkmozillapart_la_LDFLAGS = -module $(all_libraries)
+libkmozillapart_la_LIBADD = ../src/kde/libkdexparts.la
+
+servicedir = $(kde_servicesdir)
+service_DATA = kmozilla.desktop
+
+bin_PROGRAMS = kmozilla #kshell
+
+kmozilla_SOURCES = kmozilla.c kmozilla_ext.c main.c
+kmozilla_LDADD = ../src/gtk/libgtkxparts.la $(GTK_LIBS) $(GLIB_LIBS)
+kmozilla_LDFLAGS = $(GLIB_LDFLAGS) $(GTK_LDFLAGS) -L$(libdir) -L/usr/lib/mozilla -Wl,--rpath=/usr/lib/mozilla -lgtkembedmoz -lxpcom $(all_libraries)
+
+#kshell_SOURCES = kshell.cpp
+#kshell_LDADD = $(top_builddir)/xkparts/kde/libkdexparts.la
+#kshell_LDFLAGS = $(all_libraries)
+
+METASOURCES = AUTO
+
diff --git a/xparts/mozilla/README b/xparts/mozilla/README
new file mode 100644
index 00000000..48b99103
--- /dev/null
+++ b/xparts/mozilla/README
@@ -0,0 +1,2 @@
+You will need to set some environment variables for this to work. Have a look
+at env for some sample settings.
diff --git a/xparts/mozilla/configure.in.in b/xparts/mozilla/configure.in.in
new file mode 100644
index 00000000..7dc0165c
--- /dev/null
+++ b/xparts/mozilla/configure.in.in
@@ -0,0 +1,31 @@
+AC_DEFUN([AC_PATH_MOZILLA],
+[
+
+AC_MSG_CHECKING([for Mozilla development headers])
+
+mozilla_incldirs="/usr/include /usr/include/mozilla /usr/local/include /usr/X11R6/include/mozilla /opt/include /opt/mozilla/include"
+AC_FIND_FILE(gtkmozembed.h, $mozilla_incldirs, mozilla_incdir)
+
+if test "$mozilla_incdir" = NO; then
+ AC_FIND_FILE(gtkembedmoz/gtkmozembed.h, $mozilla_incldirs, mozilla_incdir)
+
+ if test "$mozilla_incdir" != NO; then
+ mozilla_incdir="$mozilla_incdir/gtkembedmoz"
+ fi
+fi
+
+if test "$mozilla_incdir" = NO; then
+ AC_MSG_RESULT(no);
+else
+ have_mozilla=yes;
+ MOZILLA_INCLUDES="-I$mozilla_incdir"
+ AC_SUBST(MOZILLA_INCLUDES)
+ AC_MSG_RESULT([found in $mozilla_incdir]);
+fi
+
+AM_CONDITIONAL(include_MOZILLA_support, [test "$mozilla_incdir" != NO])
+
+])
+
+
+AC_PATH_MOZILLA
diff --git a/xparts/mozilla/kmozilla.c b/xparts/mozilla/kmozilla.c
new file mode 100644
index 00000000..f405ef36
--- /dev/null
+++ b/xparts/mozilla/kmozilla.c
@@ -0,0 +1,193 @@
+#include "kmozilla.h"
+#include "kmozilla_ext.h"
+#include <gtkmozembed.h>
+#include <gtkbrowserextension.h>
+#include <assert.h>
+
+typedef struct _GtkKmozillaPrivate GtkKmozillaPrivate;
+
+struct _GtkKmozillaPrivate {
+ GtkMozEmbed *mozilla;
+ GtkKmozillaExtension *ext;
+};
+
+#define P ((GtkKmozillaPrivate *)(((GtkKmozilla *)part)->data))
+#define CLASS(obj) GTK_KMOZILLA_CLASS(GTK_OBJECT(obj)->klass)
+
+
+/* class and instance initialization */
+
+static void
+gtk_kmozilla_class_init(GtkKmozillaClass *klass);
+
+static void
+gtk_kmozilla_init(GtkKmozilla *part);
+
+static void
+gtk_kmozilla_destroy( GtkObject *obj );
+
+static GtkXPartClass *parent_class = 0;
+static gboolean openUrlRequested = FALSE;
+static GtkKmozilla *mozilla = 0;
+
+/* virtual functions */
+static gboolean open_url( GtkXPart *part, const char * url );
+static gboolean close_url ( GtkXPart *part );
+static char * query_extension ( GtkXPart *part, const char *name );
+
+
+/* signals */
+static void handle_reload(GtkObject *obj, gpointer user_data);
+
+/* signal handlers for gtkmozembed signals */
+static gboolean open_url_request(GtkObject *obj, const char *url);
+
+/* --------------------------- implementations --------------------------------------- */
+
+/* type information */
+GtkType
+gtk_kmozilla_get_type(void)
+{
+ static GtkType part_type = 0;
+ if (!part_type)
+ {
+ static const GtkTypeInfo part_info =
+ {
+ "GtkKmozilla",
+ sizeof(GtkKmozilla),
+ sizeof(GtkKmozillaClass),
+ (GtkClassInitFunc)gtk_kmozilla_class_init,
+ (GtkObjectInitFunc)gtk_kmozilla_init,
+ 0,
+ 0,
+ 0
+ };
+ part_type = gtk_type_unique(GTK_TYPE_XPART, &part_info);
+ }
+ return part_type;
+}
+
+/* class and instance initialization */
+static void
+gtk_kmozilla_class_init(GtkKmozillaClass *klass)
+{
+ GtkObjectClass *object_class = (GtkObjectClass *)klass;
+ GtkXPartClass *xpart_class = GTK_XPART_CLASS(klass);
+
+ parent_class = (GtkXPartClass *)gtk_type_class(gtk_xpart_get_type());
+
+ object_class->destroy = gtk_kmozilla_destroy;
+
+ xpart_class->open_url = open_url;
+ xpart_class->close_url = close_url;
+ xpart_class->query_extension = query_extension;
+
+ g_message( "gtk_kmozilla_class_init\n" );
+}
+
+static void
+gtk_kmozilla_init(GtkKmozilla *part)
+{
+ GtkWidget *w;
+ GtkWidget *moz;
+ GtkKmozillaExtension *ext;
+
+ GtkKmozillaPrivate *d;
+ d = g_new( GtkKmozillaPrivate, 1 );
+ part->data = d;
+
+ ext = gtk_kmozilla_extension_new();
+ g_message( "gtk_kmozilla_init\n" );
+ kmozilla_extension_set_mozilla( ext, part );
+ d->ext = ext;
+
+ dcop_object_set_id( DCOP_OBJECT(part), "KmozillaClient" );
+
+ w = gtk_window_new( GTK_WINDOW_TOPLEVEL );
+ moz = gtk_moz_embed_new();
+ d->mozilla = GTK_MOZ_EMBED( moz );
+ gtk_container_add( GTK_CONTAINER( w ), moz );
+ gtk_widget_realize( w );
+
+ /* g_warning( "winid %x\n", GDK_WINDOW_XWINDOW( w->window ) );*/
+
+ gtk_xpart_set_widget( (GtkXPart *)part, w );
+
+ gtk_signal_connect(GTK_OBJECT(part), "reload",
+ GTK_SIGNAL_FUNC(handle_reload), NULL);
+ gtk_signal_connect(GTK_OBJECT(moz), "open_uri",
+ GTK_SIGNAL_FUNC(open_url_request), NULL);
+
+ mozilla = part;
+ g_message( "gtk_kmozilla_init\n" );
+}
+
+GtkKmozilla *gtk_kmozilla_new (void)
+{
+ return (GtkKmozilla *) gtk_type_new(gtk_kmozilla_get_type());
+}
+
+void gtk_kmozilla_destroy( GtkObject *obj )
+{
+ GtkKmozilla *part = GTK_KMOZILLA(obj);
+ GtkKmozillaPrivate *d = (GtkKmozillaPrivate *) part->data;
+
+ gtk_object_destroy( GTK_OBJECT( d->mozilla ) );
+
+ GTK_OBJECT_CLASS(parent_class)->destroy(obj);
+}
+
+void gtk_kmozilla_set_dcop_client( GtkKmozilla *part, DcopClient *client )
+{
+ gtk_xpart_set_dcop_client(part, client);
+ gtk_xbrowserextension_set_dcop_client(P->ext, client);
+}
+
+/* ----------------------------------------------------------------------- */
+
+static gboolean open_url( GtkXPart *part, const char * url )
+{
+ g_message( "open_url %s", url );
+ openUrlRequested = FALSE;
+ gtk_moz_embed_load_url( P->mozilla, url );
+ return TRUE;
+}
+
+static gboolean close_url( GtkXPart *part )
+{
+ g_message( "close_url" );
+ gtk_moz_embed_stop_load( P->mozilla );
+ return TRUE;
+}
+
+static char * query_extension ( GtkXPart *part, const char *name )
+{
+ g_warning("KMozilla::query_extension");
+ if( !strcmp(name, "browserextension") )
+ return dcop_object_get_id((DcopObject *)P->ext);
+ return NULL;
+}
+
+static void
+handle_reload(GtkObject *obj, gpointer user_data)
+{
+ GtkKmozilla *part = GTK_KMOZILLA(obj);
+ g_message( "reload called" );
+ gtk_moz_embed_reload(P->mozilla, 0);
+}
+
+/* ----------------- signal handlers for gtkmozembed ------------------ */
+
+/* return true if we don't want mozilla to load it, false if mozilla should load the page. */
+static gboolean open_url_request(GtkObject *obj, const char * url)
+{
+ gboolean req;
+ g_message("==================>>>>>>> kmozilla::openUrlRequest %s", url);
+ req = openUrlRequested;
+ if( req == TRUE ) {
+ gtk_browserextension_open_url_request( ((GtkKmozillaPrivate *)mozilla->data)->ext, url );
+ }
+ openUrlRequested = TRUE;
+ return req;
+}
+
diff --git a/xparts/mozilla/kmozilla.desktop b/xparts/mozilla/kmozilla.desktop
new file mode 100644
index 00000000..de54312f
--- /dev/null
+++ b/xparts/mozilla/kmozilla.desktop
@@ -0,0 +1,9 @@
+[Desktop Entry]
+Type=Service
+Exec=foobar
+Comment=Embeddable HTML viewing component
+MimeType=text/html;text/xml;
+Icon=konqueror
+Name=KMOZILLA
+ServiceTypes=KParts/ReadOnlyPart,Browser/View
+X-KDE-Library=libkmozillapart
diff --git a/xparts/mozilla/kmozilla.h b/xparts/mozilla/kmozilla.h
new file mode 100644
index 00000000..c9054399
--- /dev/null
+++ b/xparts/mozilla/kmozilla.h
@@ -0,0 +1,34 @@
+#ifndef _gtk_kmozilla_h_
+#define _gtk_kmozilla_h_
+
+#include "gtkpart.h"
+
+#define GTK_TYPE_KMOZILLA (gtk_kmozilla_get_type())
+#define GTK_KMOZILLA(obj) GTK_CHECK_CAST((obj), GTK_TYPE_KMOZILLA, GtkKmozilla)
+#define GTK_KMOZILLA_CLASS(klass) GTK_CHECK_CLASS_CAST((klass), GTK_TYPE_KMOZILLA, GtkKmozillaClass)
+#define GTK_IS_KMOZILLA(obj) GTK_CHECK_TYPE((obj), GTK_TYPE_KMOZILLA)
+#define GTK_IS_KMOZILLA_CLASS(klass) GTK_CHECK_CLASS_TYPE((klass), GTK_TYPE_KMOZILLA)
+
+#define GTK_KMOZILLA_WIDGET(part) (gtk_kmozilla_get_widget(part))
+#define GTK_KMOZILLA_DCOP(part) (gtk_kmozilla_get_dcop(part))
+
+typedef struct _GtkKmozilla GtkKmozilla;
+typedef struct _GtkKmozillaClass GtkKmozillaClass;
+
+struct _GtkKmozilla
+{
+ GtkXPart part;
+ void *data;
+};
+
+struct _GtkKmozillaClass
+{
+ GtkXPartClass parent_class;
+};
+
+extern GtkType gtk_kmozilla_get_type (void);
+extern GtkKmozilla *gtk_kmozilla_new (void);
+
+void gtk_kmozilla_set_dcop_client( GtkKmozilla *part, DcopClient *client );
+
+#endif
diff --git a/xparts/mozilla/kmozilla.rc b/xparts/mozilla/kmozilla.rc
new file mode 100644
index 00000000..9c80e6c3
--- /dev/null
+++ b/xparts/mozilla/kmozilla.rc
@@ -0,0 +1,11 @@
+<!DOCTYPE kpartgui SYSTEM "kpartgui.dtd">
+<kpartgui name="khtmlpart" version="1">
+<MenuBar>
+ <Menu name="edit">
+ <Action name="stop" />
+ <Action name="reload" />
+ <Separator />
+ <Action name="nonexistant" />
+ </Menu>
+</MenuBar>
+</kpartgui>
diff --git a/xparts/mozilla/kmozilla_ext.c b/xparts/mozilla/kmozilla_ext.c
new file mode 100644
index 00000000..15195136
--- /dev/null
+++ b/xparts/mozilla/kmozilla_ext.c
@@ -0,0 +1,125 @@
+#include "kmozilla_ext.h"
+
+#include <gdk/gdkx.h>
+
+#include <dcopc/util.h>
+#include <dcopc/marshal.h>
+#include <dcopc/dcopc.h>
+
+#include <string.h>
+#include <stdio.h>
+#include <assert.h>
+#include <stdlib.h>
+
+typedef struct _GtkKmozillaExtensionPrivate GtkKmozillaExtensionPrivate;
+
+struct _GtkKmozillaExtensionPrivate {
+ GtkKmozilla *moz;
+};
+
+#define P ((GtkKmozillaExtensionPrivate *)(ext->data))
+#define CLASS(obj) GTK_KMOZILLAEXTENSION_CLASS(GTK_OBJECT(obj)->klass)
+
+
+/* class and instance initialization */
+
+static void
+gtk_kmozilla_extension_class_init(GtkKmozillaExtensionClass *klass);
+
+static void
+gtk_kmozilla_extension_init(GtkKmozillaExtension *part);
+
+static void
+gtk_kmozilla_extension_destroy( GtkObject *obj );
+
+/* virtual functions */
+static const char * save_state( GtkXBrowserExtension *ext );
+static void restore_state ( GtkXBrowserExtension *ext, const char *state, unsigned int size );
+
+static GtkXBrowserExtensionClass *parent_class = 0;
+
+/* --------------------------- implementations --------------------------------------- */
+
+/* type information */
+GtkType
+gtk_kmozilla_extension_get_type(void)
+{
+ static GtkType part_type = 0;
+ if (!part_type)
+ {
+ static const GtkTypeInfo part_info =
+ {
+ "GtkKmozillaExtension",
+ sizeof(GtkKmozillaExtension),
+ sizeof(GtkKmozillaExtensionClass),
+ (GtkClassInitFunc)gtk_kmozilla_extension_class_init,
+ (GtkObjectInitFunc)gtk_kmozilla_extension_init,
+ 0,
+ 0,
+ 0
+ };
+ part_type = gtk_type_unique(GTK_TYPE_XBROWSEREXTENSION, &part_info);
+ }
+ return part_type;
+}
+
+/* class and instance initialization */
+static void
+gtk_kmozilla_extension_class_init(GtkKmozillaExtensionClass *klass)
+{
+ GtkObjectClass *object_class = (GtkObjectClass *)klass;
+ DcopObjectClass *dcop_class = DCOP_OBJECT_CLASS(klass);
+ GtkXBrowserExtensionClass *be_class = GTK_XBROWSEREXTENSION_CLASS(klass);
+
+ parent_class = (GtkXBrowserExtensionClass *)gtk_type_class(gtk_xbrowserextension_get_type());
+
+ object_class->destroy = gtk_kmozilla_extension_destroy;
+
+ be_class->save_state = save_state;
+ be_class->restore_state = restore_state;
+
+ g_message( "gtk_kmozillaextension_class_init\n" );
+}
+
+static void
+gtk_kmozilla_extension_init(GtkKmozillaExtension *part)
+{
+ GtkKmozillaExtensionPrivate *d;
+ d = g_new( GtkKmozillaExtensionPrivate, 1 );
+ part->data = d;
+
+ dcop_object_set_id( DCOP_OBJECT(part), "KmozillaExtensionClient" );
+
+ g_message( "gtk_kmozillaextension_init\n" );
+}
+
+GtkKmozillaExtension *gtk_kmozilla_extension_new (void)
+{
+ return (GtkKmozillaExtension *) gtk_type_new(gtk_kmozilla_extension_get_type());
+}
+
+
+void gtk_kmozilla_extension_destroy( GtkObject *obj )
+{
+ GtkKmozillaExtension *part = GTK_KMOZILLA_EXTENSION(obj);
+ GtkKmozillaExtensionPrivate *d = (GtkKmozillaExtensionPrivate *) part->data;
+ g_free( d );
+
+ GTK_OBJECT_CLASS(parent_class)->destroy(obj);
+}
+
+void kmozilla_extension_set_mozilla( GtkKmozillaExtension *ext, GtkKmozilla *moz )
+{
+ P->moz = moz;
+}
+
+static const char * save_state( GtkXBrowserExtension *ext )
+{
+ g_warning("Extension::save_state!");
+ return 0;
+}
+
+static void restore_state ( GtkXBrowserExtension *ext, const char *state, unsigned int size )
+{
+ g_warning("Extension::restore_state!");
+}
diff --git a/xparts/mozilla/kmozilla_ext.h b/xparts/mozilla/kmozilla_ext.h
new file mode 100644
index 00000000..419bbc85
--- /dev/null
+++ b/xparts/mozilla/kmozilla_ext.h
@@ -0,0 +1,41 @@
+#ifndef _kmozillaextension_h__
+#define _kmozillaextension_h__
+
+#include "gtkbrowserextension.h"
+#include "kmozilla.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+#define GTK_TYPE_KMOZILLA_EXTENSION (gtk_kmozilla_extension_get_type())
+#define GTK_KMOZILLA_EXTENSION(obj) GTK_CHECK_CAST((obj), GTK_TYPE_KMOZILLA_EXTENSION, GtkKmozillaExtension)
+#define GTK_KMOZILLAEXTENSION_CLASS(klass) GTK_CHECK_CLASS_CAST((klass), GTK_TYPE_KMOZILLA_EXTENSION, GtkKmozillaExtensionClass)
+#define GTK_IS_KMOZILLA_EXTENSION(obj) GTK_CHECK_TYPE((obj), GTK_TYPE_KMOZILLA_EXTENSION)
+#define GTK_IS_KMOZILLA_EXTENSION_CLASS(klass) GTK_CHECK_CLASS_TYPE((klass), GTK_TYPE_KMOZILLA_EXTENSION)
+
+typedef struct _GtkKmozillaExtension GtkKmozillaExtension;
+typedef struct _GtkKmozillaExtensionClass GtkKmozillaExtensionClass;
+
+struct _GtkKmozillaExtension
+{
+ GtkXBrowserExtension obj;
+ void *data;
+};
+
+struct _GtkKmozillaExtensionClass
+{
+ GtkXBrowserExtensionClass parent_class;
+};
+
+extern GtkType gtk_kmozilla_extension_get_type (void);
+extern GtkKmozillaExtension *gtk_kmozilla_extension_new (void);
+
+extern void kmozilla_extension_set_mozilla( GtkKmozillaExtension *ext, GtkKmozilla *moz );
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/xparts/mozilla/kmozillapart.cpp b/xparts/mozilla/kmozillapart.cpp
new file mode 100644
index 00000000..d5f73050
--- /dev/null
+++ b/xparts/mozilla/kmozillapart.cpp
@@ -0,0 +1,51 @@
+#include "kmozillapart.h"
+
+#include <dcopclient.h>
+#include <dcopobject.h>
+#include <kapplication.h>
+#include <kstdaction.h>
+#include <kaction.h>
+#include <kmainwindow.h>
+#include <kprocess.h>
+#include <kparts/mainwindow.h>
+#include <kdebug.h>
+#include <kaboutdata.h>
+#include <kparts/genericfactory.h>
+
+typedef KParts::GenericFactory<KMozillaPart> KMozillaPartFactory;
+K_EXPORT_COMPONENT_FACTORY( libkmozillapart, KMozillaPartFactory );
+
+KMozillaPart::KMozillaPart(QWidget *parentWidget, const char *widgetName,
+ QObject *parent, const char *name, const QStringList &)
+ : XPartHost_KPart(parentWidget, widgetName, parent, name)
+{
+ setInstance( KMozillaPartFactory::instance() );
+
+ m_partProcess = new KProcess;
+ *m_partProcess << "kmozilla"
+ << kapp->dcopClient()->appId() << objId();
+ m_partProcess->start();
+
+ qDebug("---->>>>>> enter loop");
+ kapp->enter_loop();
+ qDebug("----<<<<<< left loop");
+}
+
+KMozillaPart::~KMozillaPart()
+{
+ delete m_partProcess;
+}
+
+void KMozillaPart::createActions( const QCString &xmlActions )
+{
+ XPartHost_KPart::createActions( xmlActions );
+ qDebug("----<<<<<< exit loop");
+ kapp->exit_loop();
+}
+
+KAboutData *KMozillaPart::createAboutData()
+{
+ return new KAboutData( "kmozilla", "kmozilla", "0.1" );
+}
+
+#include "kmozillapart.moc"
diff --git a/xparts/mozilla/kmozillapart.h b/xparts/mozilla/kmozillapart.h
new file mode 100644
index 00000000..d7cef4b9
--- /dev/null
+++ b/xparts/mozilla/kmozillapart.h
@@ -0,0 +1,27 @@
+#ifndef _kmozillapart_h_
+#define _kmozillapart_h_
+
+#include "xparthost_kpart.h"
+
+class KAboutData;
+class KProcess;
+
+class KMozillaPart : public XPartHost_KPart
+{
+ Q_OBJECT
+
+public:
+ KMozillaPart(QWidget *parentWidget, const char *widgetName,
+ QObject *parent, const char *name, const QStringList &);
+ virtual ~KMozillaPart();
+
+ virtual void createActions( const QCString &xmlActions );
+
+ static KAboutData *createAboutData();
+
+private:
+ KProcess *m_partProcess;
+};
+
+#endif
+
diff --git a/xparts/mozilla/kshell.cpp b/xparts/mozilla/kshell.cpp
new file mode 100644
index 00000000..4f012dbb
--- /dev/null
+++ b/xparts/mozilla/kshell.cpp
@@ -0,0 +1,76 @@
+
+#include "xparthost_kpart.h"
+
+#include <dcopclient.h>
+#include <dcopobject.h>
+#include <kapplication.h>
+#include <kstdaction.h>
+#include <kaction.h>
+#include <kmainwindow.h>
+#include <kprocess.h>
+#include <kparts/mainwindow.h>
+#include <kdebug.h>
+
+class ShellWindow : public KParts::MainWindow
+{
+ Q_OBJECT
+
+public:
+ ShellWindow()
+ {
+ m_host = new XPartHost_KPart( this, "parthost" );
+
+ setCentralWidget( m_host->widget() );
+
+ connect(m_host, SIGNAL( actionsInitialized() ), this, SLOT( mergeGUI() ) );
+
+#if 1
+ m_partProcess = new KProcess;
+ *m_partProcess << "./kmozilla"
+ << kapp->dcopClient()->appId() << m_host->objId();
+ m_partProcess->start();
+#endif
+
+ KStdAction::quit( this, SLOT( close() ), actionCollection() );
+ KSelectAction *s = new KSelectAction( "http://www.kde.org" , 0,
+ actionCollection(), "location" );
+ connect( s, SIGNAL(activated( const QString& ) ), this, SLOT( slotOpenUrl( const QString & ) ) );
+ s->setEditable(true);
+ }
+ virtual ~ShellWindow()
+ {
+ delete m_partProcess;
+ }
+public slots:
+ void slotOpenUrl( const QString &url )
+ {
+ kdDebug() << "this=" << this;
+ kdDebug() << "url=" << url << endl;
+ m_host->openURL(url.latin1());
+ }
+ void mergeGUI()
+ {
+ qDebug("initGUI");
+ setXMLFile("/home/lars/kmozilla/kmozilla/parthost.rc");
+ createGUI( m_host );
+ }
+
+private:
+ XPartHost_KPart *m_host;
+ KProcess *m_partProcess;
+};
+
+int main( int argc, char **argv )
+{
+ KApplication app( argc, argv, "xkpartsshell" );
+
+ app.dcopClient()->registerAs("kshell");
+
+ ShellWindow *w = new ShellWindow;
+ w->resize(500, 500);
+ w->show();
+
+ return app.exec();
+}
+
+#include "kshell.moc"
diff --git a/xparts/mozilla/main.c b/xparts/mozilla/main.c
new file mode 100644
index 00000000..c4b8e3ca
--- /dev/null
+++ b/xparts/mozilla/main.c
@@ -0,0 +1,69 @@
+#include "kmozilla.h"
+#include <dcopc/dcopc.h>
+#include "gtkpart.h"
+
+#include <stdio.h>
+
+gboolean dcop_socket_notify( GIOChannel *chan, GIOCondition condition, gpointer data )
+{
+ DcopClient *client = (DcopClient *)data;
+ g_warning( "dcop_socket_notify\n" );
+ dcop_client_process_socket_data( client );
+ return TRUE;
+}
+
+void gtktest_exit()
+{
+ g_warning( "EXIT!\n" );
+ gtk_main_quit();
+}
+
+
+int main( int argc, char **argv )
+{
+ GtkKmozilla *moz;
+ GtkXPart *part;
+ DcopClient *client;
+ GIOChannel *socket_chan;
+
+ gtk_init( &argc, &argv );
+
+ moz = gtk_kmozilla_new( );
+ part = (GtkXPart *)moz;
+ client = dcop_client_new();
+/* dcop_client_attach( client );*/
+ /* for debugging*/
+ dcop_client_register_as( client, "kmozilla", TRUE );
+
+ socket_chan = g_io_channel_unix_new( dcop_client_socket( client ) );
+ g_io_channel_ref( socket_chan );
+ g_io_add_watch( socket_chan, G_IO_IN, dcop_socket_notify, client );
+
+ fprintf(stderr, "client initialized!\n");
+
+ gtk_kmozilla_set_dcop_client(part, client);
+ if(!gtk_xpart_register(part, argv[1], argv[2]))
+ fprintf(stderr, "could not register part\n");
+
+ {
+ /* initialize actions */
+ const char * actions = "<!DOCTYPE actionList SYSTEM \"actionlist.dtd\">\n"
+ "<Actionlist>\n"
+ " <Action name=\"stop\" />\n"
+ " <Action name=\"reload\" />\n"
+ " <Action name=\"nonexistant\" />\n"
+ " <XMLFile location=\"./kmozilla.rc\" />\n"
+ "</Actionlist>\n";
+ gtk_xpart_initialize_actions( part, actions );
+ fprintf(stderr, "hopfully initialized actions\n");
+ }
+ fprintf(stderr, "done!\n");
+
+ gtk_main();
+
+ g_io_channel_unref( socket_chan );
+
+ gtk_object_destroy( GTK_OBJECT(client) );
+
+ return 0;
+}
diff --git a/xparts/mozilla/parthost.rc b/xparts/mozilla/parthost.rc
new file mode 100644
index 00000000..6d451d8d
--- /dev/null
+++ b/xparts/mozilla/parthost.rc
@@ -0,0 +1,14 @@
+<!DOCTYPE kpartgui SYSTEM "kpartgui.dtd">
+<kpartgui name="part" version="1">
+<MenuBar>
+ <Menu name="edit">
+ <Action name="stop" />
+ <Action name="reload" />
+ <Separator />
+ <Action name="nonexistant" />
+ </Menu>
+</MenuBar>
+<ToolBar fullWidth="true" name="locationToolBar" newline="true">
+ <Action name="location" />
+</ToolBar>
+</kpartgui>
diff --git a/xparts/src/Makefile.am b/xparts/src/Makefile.am
new file mode 100644
index 00000000..243ba3b3
--- /dev/null
+++ b/xparts/src/Makefile.am
@@ -0,0 +1,7 @@
+
+if include_GTK_support
+SUPPORTGTKDIR=gtk
+endif
+
+SUBDIRS = interfaces kde $(SUPPORTGTKDIR)
+
diff --git a/xparts/src/gtk/Makefile.am b/xparts/src/gtk/Makefile.am
new file mode 100644
index 00000000..2e83df3b
--- /dev/null
+++ b/xparts/src/gtk/Makefile.am
@@ -0,0 +1,13 @@
+INCLUDES = $(GLIB_INCLUDES) -I$(prefix)/include -I$(top_srcdir) $(all_includes)
+
+AM_CFLAGS = $(GLIB_CFLAGS) $(GTK_CFLAGS)
+AM_CXXFLAGS = $(GLIB_CFLAGS) $(GTK_CFLAGS)
+
+lib_LTLIBRARIES = libgtkxparts.la
+
+libgtkxparts_la_SOURCES = gtkpart.c gtkbrowserextension.c
+libgtkxparts_la_LIBADD = $(GTK_LIBS) $(GLIB_LIBS) $(top_builddir)/dcopc/libdcopc.la
+libgtkxparts_la_LDFLAGS = -L$(prefix)/lib $(all_libraries) -no-undefined
+
+gtkxpartsinclude_HEADERS = gtkpart.h gtkbrowserextension.h
+gtkxpartsincludedir = $(includedir)/xkparts
diff --git a/xparts/src/gtk/configure.in.in b/xparts/src/gtk/configure.in.in
new file mode 100644
index 00000000..32dfac1e
--- /dev/null
+++ b/xparts/src/gtk/configure.in.in
@@ -0,0 +1 @@
+AM_CONDITIONAL(include_GTK_support, [ test "$GTK_CONFIG" != "no" ])
diff --git a/xparts/src/gtk/gtkbrowserextension.c b/xparts/src/gtk/gtkbrowserextension.c
new file mode 100644
index 00000000..165320a8
--- /dev/null
+++ b/xparts/src/gtk/gtkbrowserextension.c
@@ -0,0 +1,244 @@
+
+#include "gtkbrowserextension.h"
+
+#include <gdk/gdkx.h>
+
+#include <dcopc/util.h>
+#include <dcopc/marshal.h>
+#include <dcopc/dcopc.h>
+
+#include <string.h>
+#include <stdio.h>
+#include <assert.h>
+#include <stdlib.h>
+
+typedef struct _GtkXBrowserExtensionPrivate GtkXBrowserExtensionPrivate;
+
+struct _GtkXBrowserExtensionPrivate {
+ gchar *host_app_id;
+ gchar *host_obj_id;
+ DcopClient *client;
+};
+
+#define P ((GtkXBrowserExtensionPrivate *)(part->data))
+#define CLASS(obj) GTK_XBROWSEREXTENSION_CLASS(GTK_OBJECT(obj)->klass)
+
+
+/* class and instance initialization */
+
+static void
+gtk_xbrowserextension_class_init(GtkXBrowserExtensionClass *klass);
+
+static void
+gtk_xbrowserextension_init(GtkXBrowserExtension *part);
+
+static void
+gtk_xbrowserextension_destroy( GtkObject *obj );
+
+
+/* dcop handlers */
+
+gboolean gtk_xbrowserextension_dcop_process( DcopObject *obj, const char *fun, dcop_data *data,
+ char **reply_type, dcop_data **reply_data );
+
+GList *gtk_xbrowserextension_dcop_functions( DcopObject *obj );
+
+GList *gtk_xbrowserextension_dcop_interfaces( DcopObject *obj );
+
+static DcopObjectClass *parent_class = 0;
+
+/* --------------------------- implementations --------------------------------------- */
+
+/* type information */
+GtkType
+gtk_xbrowserextension_get_type(void)
+{
+ static GtkType part_type = 0;
+ if (!part_type)
+ {
+ static const GtkTypeInfo part_info =
+ {
+ "GtkXBrowserExtension",
+ sizeof(GtkXBrowserExtension),
+ sizeof(GtkXBrowserExtensionClass),
+ (GtkClassInitFunc)gtk_xbrowserextension_class_init,
+ (GtkObjectInitFunc)gtk_xbrowserextension_init,
+ 0,
+ 0,
+ 0
+ };
+ part_type = gtk_type_unique(DCOP_TYPE_OBJECT, &part_info);
+ }
+ return part_type;
+}
+
+/* class and instance initialization */
+static void
+gtk_xbrowserextension_class_init(GtkXBrowserExtensionClass *klass)
+{
+ GtkObjectClass *object_class = (GtkObjectClass *)klass;
+ DcopObjectClass *dcop_class = DCOP_OBJECT_CLASS(klass);
+ g_message( "gtk_xbrowserextension_class_init\n" );
+
+ parent_class = (DcopObjectClass *)gtk_type_class(dcop_object_get_type());
+
+ object_class->destroy = gtk_xbrowserextension_destroy;
+
+ dcop_class->process = gtk_xbrowserextension_dcop_process;
+ dcop_class->functions = gtk_xbrowserextension_dcop_functions;
+ dcop_class->interfaces = gtk_xbrowserextension_dcop_interfaces;
+
+ klass->save_state = 0;
+ klass->restore_state = 0;
+
+ g_message( "gtk_xbrowserextension_class_init\n" );
+}
+
+static void
+gtk_xbrowserextension_init(GtkXBrowserExtension *part)
+{
+ GtkXBrowserExtensionPrivate *d;
+ d = g_new( GtkXBrowserExtensionPrivate, 1 );
+ part->data = d;
+
+ dcop_object_set_id( DCOP_OBJECT(part), "XBrowserExtensionClient" );
+
+ d->client = 0;
+ d->host_app_id = 0;
+ d->host_obj_id = 0;
+
+ g_message( "gtk_xbrowserextension_init\n" );
+}
+
+GtkXBrowserExtension *gtk_xbrowserextension_new (void)
+{
+ return (GtkXBrowserExtension *) gtk_type_new(gtk_xbrowserextension_get_type());
+}
+
+
+gboolean gtk_xbrowserextension_dcop_process( DcopObject *obj, const char *fun, dcop_data *data,
+ char **reply_type, dcop_data **reply_data )
+{
+ GtkXBrowserExtension *part = GTK_XBROWSEREXTENSION(obj);
+ GtkXBrowserExtensionPrivate *d = (GtkXBrowserExtensionPrivate *)part->data;
+ GtkXBrowserExtensionClass *klass = GTK_XBROWSEREXTENSION_CLASS(GTK_OBJECT(part)->klass);
+
+ if ( strcmp( fun, "saveState()" ) == 0 )
+ {
+ const char *state = 0;
+ if( klass->save_state) {
+ state = klass->save_state( part );
+
+ dcop_marshal_bytearray( *reply_data, state, strlen( state ) );
+ }
+ return True;
+ }
+ else if ( strcmp( fun, "restoreState(QByteArray)" ) == 0 )
+ {
+ if( klass->restore_state ) {
+ size_t len;
+ char *state;
+ dcop_demarshal_bytearray( data, &state, &len );
+ klass->restore_state( part, state, len );
+ }
+ return True;
+ }
+ else if ( strcmp( fun, "setBrowserSignals(DCOPRef)" ) == 0 )
+ {
+ dcop_demarshal_string( data, &d->host_app_id );
+ dcop_demarshal_string( data, &d->host_obj_id );
+ return True;
+ }
+
+ return parent_class->process( obj, fun, data, reply_type, reply_data );
+}
+
+GList *gtk_xbrowserextension_dcop_functions( DcopObject *obj )
+{
+ GList *res = parent_class->functions( obj );
+ res = g_list_append( res, g_strdup( "saveState()" ) );
+ res = g_list_append( res, g_strdup( "restoreState(QByteArray)" ) );
+ return res;
+}
+
+GList *gtk_xbrowserextension_dcop_interfaces( DcopObject *obj )
+{
+ GList *res = parent_class->interfaces( obj );
+ res = g_list_append( res, g_strdup( "XBrowserExtension" ) );
+ return res;
+}
+
+void gtk_xbrowserextension_destroy( GtkObject *obj )
+{
+ GtkXBrowserExtension *part = GTK_XBROWSEREXTENSION(obj);
+ GtkXBrowserExtensionPrivate *d = (GtkXBrowserExtensionPrivate *) part->data;
+ g_free( d->host_app_id );
+ g_free( d->host_obj_id );
+ g_free( d );
+
+ GTK_OBJECT_CLASS(parent_class)->destroy(obj);
+}
+
+void gtk_xbrowserextension_set_dcop_client( GtkXBrowserExtension *part, DcopClient *client )
+{
+ P->client = client;
+}
+
+
+gboolean gtk_xbrowserextension_register( GtkXBrowserExtension *part, const gchar *host_app_id, const gchar *host_obj_id)
+{
+ dcop_data *reply_data;
+ char *reply_type;
+ dcop_data *data = dcop_data_ref( dcop_data_new() );
+ GtkXBrowserExtensionPrivate *d = (GtkXBrowserExtensionPrivate *)part->data;
+
+ if(!P->client)
+ fprintf(stderr, "register a dcop client first!\n");
+
+ dcop_marshal_string( data, dcop_client_app_id( P->client ) );
+ dcop_marshal_string( data, DCOP_ID(DCOP_OBJECT(part)) );
+
+ if ( !dcop_client_call( P->client, host_app_id, host_obj_id, "registerXBrowserExtension(DCOPRef)", data,
+ &reply_type, &reply_data ) ) {
+ fprintf( stderr, "cannot register with shell %s / %s\n", host_app_id, host_obj_id );
+ gtk_exit( 1 );
+ }
+ g_message( "back from registration call!" );
+
+ /*assert( strcmp( reply_type, "DCOPRef" ) == 0 );*/
+
+#if 0
+ /* this is wrong. but as we have the ref anyway, let's ignore the return value*/
+ dcop_demarshal_string( data, &d->host_app_id );
+ dcop_demarshal_string( data, &d->host_obj_id );
+
+ printf("appid=%s, objid=%s\n", d->host_app_id, d->host_obj_id);
+#endif
+ d->host_obj_id = g_strdup( host_obj_id );
+ d->host_app_id = g_strdup( host_app_id );
+
+ dcop_data_reset( reply_data );
+
+ dcop_data_deref( data );
+ g_message( "returning from gtk_xbrowserextension_register" );
+ return TRUE;
+}
+
+gboolean gtk_browserextension_open_url_request( GtkXBrowserExtension *part, const char *url )
+{
+ dcop_data *reply_data;
+ char *reply_type;
+ dcop_data *data = dcop_data_ref( dcop_data_new() );
+
+ if(!P->client)
+ fprintf(stderr, "register a dcop client first!\n");
+
+ dcop_marshal_string( data, url );
+
+ if ( !dcop_client_call( P->client, P->host_app_id, P->host_obj_id, "openURLRequest(QCString)", data,
+ &reply_type, &reply_data ) ) {
+ g_warning(" openURLRequest failed");
+ return FALSE;
+ }
+ return TRUE;
+}
diff --git a/xparts/src/gtk/gtkbrowserextension.h b/xparts/src/gtk/gtkbrowserextension.h
new file mode 100644
index 00000000..7efbd938
--- /dev/null
+++ b/xparts/src/gtk/gtkbrowserextension.h
@@ -0,0 +1,54 @@
+#ifndef _gtkxbrowserextension_h__
+#define _gtkxbrowserextension_h__
+
+#include <dcopc/dcopobject.h>
+#include <dcopc/dcopc.h>
+#include <dcopc/marshal.h>
+#include <dcopc/util.h>
+
+#include <gtk/gtk.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define GTK_TYPE_XBROWSEREXTENSION (gtk_xbrowserextension_get_type())
+#define GTK_XBROWSEREXTENSION(obj) GTK_CHECK_CAST((obj), GTK_TYPE_XBROWSEREXTENSION, GtkXBrowserExtension)
+#define GTK_XBROWSEREXTENSION_CLASS(klass) GTK_CHECK_CLASS_CAST((klass), GTK_TYPE_XBROWSEREXTENSION, GtkXBrowserExtensionClass)
+#define GTK_IS_XBROWSEREXTENSION(obj) GTK_CHECK_TYPE((obj), GTK_TYPE_XBROWSEREXTENSION)
+#define GTK_IS_XBROWSEREXTENSION_CLASS(klass) GTK_CHECK_CLASS_TYPE((klass), GTK_TYPE_XBROWSEREXTENSION)
+
+#define GTK_XBROWSEREXTENSION_WIDGET(part) (gtk_xbrowserextension_get_widget(part))
+#define GTK_XBROWSEREXTENSION_DCOP(part) (gtk_xbrowserextension_get_dcop(part))
+
+typedef struct _GtkXBrowserExtension GtkXBrowserExtension;
+typedef struct _GtkXBrowserExtensionClass GtkXBrowserExtensionClass;
+
+struct _GtkXBrowserExtension
+{
+ DcopObject obj;
+ void *data;
+};
+
+struct _GtkXBrowserExtensionClass
+{
+ DcopObjectClass parent_class;
+
+ const char * ( *save_state)( GtkXBrowserExtension *ext );
+ void (* restore_state) ( GtkXBrowserExtension *ext, const char *state, unsigned int size );
+};
+
+extern GtkType gtk_xbrowserextension_get_type (void);
+extern GtkXBrowserExtension *gtk_xbrowserextension_new (void);
+
+gboolean gtk_browserextension_open_url_request( GtkXBrowserExtension *ext, const char *url );
+
+/* "virtual" functions from DcopObject */
+void gtk_xbrowserextension_set_dcop_client( GtkXBrowserExtension *part, DcopClient *client );
+gboolean gtk_xbrowserextension_register( GtkXBrowserExtension *part, const gchar *host_app_id, const gchar *host_obj_id);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/xparts/src/gtk/gtkpart.c b/xparts/src/gtk/gtkpart.c
new file mode 100644
index 00000000..740910fb
--- /dev/null
+++ b/xparts/src/gtk/gtkpart.c
@@ -0,0 +1,299 @@
+
+#include "gtkpart.h"
+
+#include <gdk/gdkx.h>
+
+#include <dcopc/util.h>
+#include <dcopc/marshal.h>
+#include <dcopc/dcopc.h>
+
+#include <string.h>
+#include <stdio.h>
+#include <assert.h>
+#include <stdlib.h>
+
+typedef struct _GtkXPartPrivate GtkXPartPrivate;
+
+struct _GtkXPartPrivate {
+ GtkWidget *widget;
+ gchar *host_app_id;
+ gchar *host_obj_id;
+ DcopClient *client;
+};
+
+#define P ((GtkXPartPrivate *)(part->data))
+#define CLASS(obj) GTK_XPART_CLASS(GTK_OBJECT(obj)->klass)
+
+
+/* class and instance initialization */
+
+static void
+gtk_xpart_class_init(GtkXPartClass *klass);
+
+static void
+gtk_xpart_init(GtkXPart *part);
+
+static void
+gtk_xpart_destroy( GtkObject *obj );
+
+/* dcop handlers */
+
+gboolean gtk_xpart_dcop_process( DcopObject *obj, const char *fun, dcop_data *data,
+ char **reply_type, dcop_data **reply_data );
+
+GList *gtk_xpart_dcop_functions( DcopObject *obj );
+
+GList *gtk_xpart_dcop_interfaces( DcopObject *obj );
+
+static DcopObjectClass *parent_class = 0;
+
+/* --------------------------- implementations --------------------------------------- */
+
+/* type information */
+GtkType
+gtk_xpart_get_type(void)
+{
+ static GtkType part_type = 0;
+ if (!part_type)
+ {
+ static const GtkTypeInfo part_info =
+ {
+ "GtkXPart",
+ sizeof(GtkXPart),
+ sizeof(GtkXPartClass),
+ (GtkClassInitFunc)gtk_xpart_class_init,
+ (GtkObjectInitFunc)gtk_xpart_init,
+ 0,
+ 0,
+ 0
+ };
+ part_type = gtk_type_unique(DCOP_TYPE_OBJECT, &part_info);
+ }
+ return part_type;
+}
+
+/* class and instance initialization */
+static void
+gtk_xpart_class_init(GtkXPartClass *klass)
+{
+ GtkObjectClass *object_class = (GtkObjectClass *)klass;
+ DcopObjectClass *dcop_class = DCOP_OBJECT_CLASS(klass);
+
+ parent_class = (DcopObjectClass *)gtk_type_class(dcop_object_get_type());
+
+ object_class->destroy = gtk_xpart_destroy;
+
+ dcop_class->process = gtk_xpart_dcop_process;
+ dcop_class->functions = gtk_xpart_dcop_functions;
+ dcop_class->interfaces = gtk_xpart_dcop_interfaces;
+
+ klass->open_url = 0;
+ klass->close_url = 0;
+ klass->query_extension = 0;
+
+ g_message( "gtk_xpart_class_init\n" );
+}
+
+static void
+gtk_xpart_init(GtkXPart *part)
+{
+ GtkXPartPrivate *d;
+ d = g_new( GtkXPartPrivate, 1 );
+ part->data = d;
+
+ dcop_object_set_id( DCOP_OBJECT(part), "XPartClient" );
+
+ d->widget = 0;
+ d->client = 0;
+ d->host_app_id = 0;
+ d->host_obj_id = 0;
+
+ g_message( "gtk_xpart_init\n" );
+}
+
+GtkXPart *gtk_xpart_new (void)
+{
+ return (GtkXPart *) gtk_type_new(gtk_xpart_get_type());
+}
+
+
+void gtk_xpart_set_widget( GtkXPart *part, GtkWidget *widget )
+{
+ GtkXPartPrivate *d = (GtkXPartPrivate *)part->data;
+ d->widget = widget;
+ gtk_object_ref( GTK_OBJECT( widget ) );
+}
+
+
+
+gboolean gtk_xpart_dcop_process( DcopObject *obj, const char *fun, dcop_data *data,
+ char **reply_type, dcop_data **reply_data )
+{
+ GtkXPart *part = GTK_XPART(obj);
+ GtkXPartPrivate *d = (GtkXPartPrivate *)part->data;
+ GtkXPartClass *klass = GTK_XPART_CLASS(GTK_OBJECT(part)->klass);
+ gboolean b;
+
+ if ( strcmp( fun, "windowId()" ) == 0 )
+ {
+ *reply_type = strdup( "Q_UINT32" );
+ *reply_data = dcop_data_ref( dcop_data_new() );
+
+ fprintf( stderr, "returning window id %ld\n", GDK_WINDOW_XWINDOW( d->widget->window ) );
+ dcop_marshal_uint32( *reply_data, GDK_WINDOW_XWINDOW( d->widget->window ) );
+
+ return True;
+ }
+ else if ( strcmp( fun, "show()" ) == 0 )
+ {
+ fprintf( stderr, "show %p!\n", d->widget );
+ gtk_widget_show_all( d->widget );
+ return True;
+ }
+ else if ( strcmp( fun, "openURL(QCString)" ) == 0 )
+ {
+ char *url;
+ fprintf( stderr, "openURL!\n" );
+ dcop_demarshal_string( data, &url );
+ b = FALSE;
+ if ( klass->open_url )
+ b = klass->open_url( part, url );
+ *reply_type = strdup( "bool" );
+ *reply_data = dcop_data_ref( dcop_data_new() );
+ dcop_marshal_boolean( *reply_data, b );
+ return True;
+ }
+ else if ( strcmp( fun, "closeURL()" ) == 0 )
+ {
+ fprintf( stderr, "closeURL!\n" );
+ b = FALSE;
+ if ( klass->close_url )
+ b = klass->close_url( part );
+ *reply_type = strdup( "bool" );
+ *reply_data = dcop_data_ref( dcop_data_new() );
+ dcop_marshal_boolean( *reply_data, b );
+ return True;
+ }
+ else if ( strcmp( fun, "activateAction(QCString,int)" ) == 0 )
+ {
+ char *name;
+ uint state;
+ dcop_demarshal_string( data, &name );
+ dcop_demarshal_uint32( data, &state );
+ fprintf( stderr, "activateAction %s state=%d\n", name, state );
+ gtk_signal_emit_by_name( GTK_OBJECT(part), name, state);
+ return True;
+ }
+ else if ( strcmp( fun, "queryExtension(QCString)" ) == 0 ) {
+ char *name;
+ char *extension = NULL;
+ dcop_demarshal_string( data, &name );
+ if ( klass->query_extension )
+ extension = klass->query_extension( part, name );
+ *reply_type = strdup( "DCOPRef" );
+ *reply_data = dcop_data_ref( dcop_data_new() );
+ dcop_marshal_string( *reply_data, dcop_client_app_id( P->client ) );
+ dcop_marshal_string( *reply_data, extension );
+ return True;
+ }
+
+ return parent_class->process( obj, fun, data, reply_type, reply_data );
+}
+
+GList *gtk_xpart_dcop_functions( DcopObject *obj )
+{
+ GList *res = parent_class->functions( obj );
+ res = g_list_append( res, g_strdup( "windowId()" ) );
+ res = g_list_append( res, g_strdup( "show()" ) );
+ res = g_list_append( res, g_strdup( "bool openURL(QString url)" ) );
+ res = g_list_append( res, g_strdup( "bool closeURL()" ) );
+ res = g_list_append( res, g_strdup( "queryExtension(QCString)" ) );
+ return res;
+}
+
+GList *gtk_xpart_dcop_interfaces( DcopObject *obj )
+{
+ GList *res = parent_class->interfaces( obj );
+ res = g_list_append( res, g_strdup( "XPart" ) );
+ return res;
+}
+
+void gtk_xpart_destroy( GtkObject *obj )
+{
+ GtkXPart *part = GTK_XPART(obj);
+ GtkXPartPrivate *d = (GtkXPartPrivate *) part->data;
+ g_free( d->host_app_id );
+ g_free( d->host_obj_id );
+
+ gtk_object_destroy( GTK_OBJECT( d->widget ) );
+
+ GTK_OBJECT_CLASS(parent_class)->destroy(obj);
+}
+
+void gtk_xpart_set_dcop_client( GtkXPart *part, DcopClient *client )
+{
+ P->client = client;
+}
+
+
+gboolean gtk_xpart_register( GtkXPart *part, const gchar *host_app_id, const gchar *host_obj_id)
+{
+ dcop_data *reply_data;
+ char *reply_type;
+ dcop_data *data = dcop_data_ref( dcop_data_new() );
+ GtkXPartPrivate *d = (GtkXPartPrivate *)part->data;
+
+ if(!P->client)
+ fprintf(stderr, "register a dcop client first!\n");
+
+ dcop_marshal_string( data, dcop_client_app_id( P->client ) );
+ dcop_marshal_string( data, DCOP_ID(DCOP_OBJECT(part)) );
+
+ if ( !dcop_client_call( P->client, host_app_id, host_obj_id, "registerXPart(DCOPRef)", data,
+ &reply_type, &reply_data ) ) {
+ fprintf( stderr, "cannot register with shell %s / %s\n", host_app_id, host_obj_id );
+ gtk_exit( 1 );
+ }
+ g_message( "back from registration call!" );
+
+ /*assert( strcmp( reply_type, "DCOPRef" ) == 0 );*/
+
+#if 0
+ /* this is wrong. but as we have the ref anyway, let's ignore the return value*/
+ dcop_demarshal_string( data, &d->host_app_id );
+ dcop_demarshal_string( data, &d->host_obj_id );
+
+ printf("appid=%s, objid=%s\n", d->host_app_id, d->host_obj_id);
+#endif
+ d->host_obj_id = g_strdup( host_obj_id );
+ d->host_app_id = g_strdup( host_app_id );
+
+ dcop_data_reset( reply_data );
+
+ dcop_data_deref( data );
+ g_message( "returning from gtk_xpart_register" );
+ return TRUE;
+}
+
+
+gboolean gtk_xpart_initialize_actions( GtkXPart *part, const char * actions )
+{
+ GtkXPartPrivate *d = (GtkXPartPrivate *) part->data;
+ dcop_data *data = 0;
+
+ g_message( "gtk_xpart_initialize_actions\n" );
+
+ if(!P->client)
+ g_message( "register a dcop client first!\n" );
+
+ data = dcop_data_ref( dcop_data_new() );
+ dcop_marshal_string( data, actions );
+
+ if( !dcop_client_send( d->client, d->host_app_id, d->host_obj_id, "createActions(QCString)", data ) ) {
+ fprintf( stderr, "could not create actions\n" );
+ dcop_data_deref( data );
+ return FALSE;
+ }
+ dcop_data_deref( data );
+ return TRUE;
+}
diff --git a/xparts/src/gtk/gtkpart.h b/xparts/src/gtk/gtkpart.h
new file mode 100644
index 00000000..e803f03e
--- /dev/null
+++ b/xparts/src/gtk/gtkpart.h
@@ -0,0 +1,61 @@
+#ifndef _gtkxpart_h__
+#define _gtkxpart_h__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <dcopc/dcopobject.h>
+#include <dcopc/dcopc.h>
+#include <dcopc/marshal.h>
+#include <dcopc/util.h>
+
+#include <gtk/gtk.h>
+
+#include "gtkbrowserextension.h"
+
+#define GTK_TYPE_XPART (gtk_xpart_get_type())
+#define GTK_XPART(obj) GTK_CHECK_CAST((obj), GTK_TYPE_XPART, GtkXPart)
+#define GTK_XPART_CLASS(klass) GTK_CHECK_CLASS_CAST((klass), GTK_TYPE_XPART, GtkXPartClass)
+#define GTK_IS_XPART(obj) GTK_CHECK_TYPE((obj), GTK_TYPE_XPART)
+#define GTK_IS_XPART_CLASS(klass) GTK_CHECK_CLASS_TYPE((klass), GTK_TYPE_XPART)
+
+#define GTK_XPART_WIDGET(part) (gtk_xpart_get_widget(part))
+#define GTK_XPART_DCOP(part) (gtk_xpart_get_dcop(part))
+
+typedef struct _GtkXPart GtkXPart;
+typedef struct _GtkXPartClass GtkXPartClass;
+
+struct _GtkXPart
+{
+ DcopObject obj;
+ void *data;
+};
+
+struct _GtkXPartClass
+{
+ DcopObjectClass parent_class;
+
+ gboolean (* open_url) ( GtkXPart *part, const char * url );
+ gboolean (* close_url) ( GtkXPart *part );
+
+ /* virtual function, returns the dcop object id of the extension, or NULL if it
+ doesn't exist */
+ char * (*query_extension) ( GtkXPart *part, const char *name );
+};
+
+extern GtkType gtk_xpart_get_type (void);
+extern GtkXPart *gtk_xpart_new (void);
+
+/* "virtual" functions from DcopObject */
+void gtk_xpart_set_dcop_client( GtkXPart *part, DcopClient *client );
+gboolean gtk_xpart_register( GtkXPart *part, const gchar *host_app_id, const gchar *host_obj_id);
+gboolean gtk_xpart_initialize_actions( GtkXPart *part, const char * actions );
+
+void gtk_xpart_set_widget( GtkXPart *part, GtkWidget *widget );
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/xparts/src/interfaces/Makefile.am b/xparts/src/interfaces/Makefile.am
new file mode 100644
index 00000000..0d4b7f97
--- /dev/null
+++ b/xparts/src/interfaces/Makefile.am
@@ -0,0 +1,3 @@
+
+xkpartsinclude_HEADERS = xpart.h xparthost.h
+xkpartsincludedir = $(includedir)/xkparts
diff --git a/xparts/src/interfaces/xbrowserextension.h b/xparts/src/interfaces/xbrowserextension.h
new file mode 100644
index 00000000..57297441
--- /dev/null
+++ b/xparts/src/interfaces/xbrowserextension.h
@@ -0,0 +1,17 @@
+#ifndef __xpart_browser_h__
+#define __xpart_browser_h__
+
+#include <dcopref.h>
+
+class XBrowserExtension : public DCOPObject
+{
+ K_DCOP
+
+k_dcop:
+ virtual void setBrowserSignals( const DCOPRef &ref) = 0;
+
+ virtual QByteArray saveState() = 0;
+ virtual void restoreState( QByteArray state ) = 0;
+};
+
+#endif
diff --git a/xparts/src/interfaces/xbrowsersignals.h b/xparts/src/interfaces/xbrowsersignals.h
new file mode 100644
index 00000000..6d41d28b
--- /dev/null
+++ b/xparts/src/interfaces/xbrowsersignals.h
@@ -0,0 +1,15 @@
+#ifndef __xpart_browsersignals_h__
+#define __xpart_browsersignals_h__
+
+#include <dcopobject.h>
+
+class XBrowserSignals : public DCOPObject
+{
+ K_DCOP
+
+k_dcop:
+ virtual ASYNC openURLRequest( const QCString &url) = 0;
+ virtual ASYNC createNewWindow( const QCString &url ) = 0;
+};
+
+#endif
diff --git a/xparts/src/interfaces/xpart.h b/xparts/src/interfaces/xpart.h
new file mode 100644
index 00000000..7722f5fb
--- /dev/null
+++ b/xparts/src/interfaces/xpart.h
@@ -0,0 +1,36 @@
+#ifndef __xkparts_part_h__
+#define __xkparts_part_h__
+
+#include <dcopobject.h>
+#include <dcopref.h>
+#include <qglobal.h>
+
+class XPart : public DCOPObject
+{
+ K_DCOP
+k_dcop:
+
+ /** The XPartManager uses the windowId() to embed the part. */
+ virtual Q_UINT32 windowId() = 0;
+
+ /** Called when the part should display itself */
+ virtual void show() = 0;
+
+ /** sent by the XPartHost to request url opening */
+ virtual bool openURL( const QCString& url ) = 0;
+
+ /** sent by the XPartHost to close the url */
+ virtual bool closeURL() = 0;
+
+ /** Called when an action (previously registered with
+ * XPartHost::createActions()) has been activated. Name is the name of the
+ * action, state is used with Toggle actions to precise the current state.
+ */
+ virtual ASYNC activateAction( const QString &name, int state ) = 0;
+
+ /** Are extentions available -> browser extension / TextEditor ? */
+ virtual DCOPRef queryExtension( const QCString& extension ) = 0;
+
+};
+
+#endif
diff --git a/xparts/src/interfaces/xparthost.h b/xparts/src/interfaces/xparthost.h
new file mode 100644
index 00000000..3d1d95f4
--- /dev/null
+++ b/xparts/src/interfaces/xparthost.h
@@ -0,0 +1,53 @@
+#ifndef __xkparts_parthost_h__
+#define __xkparts_parthost_h__
+
+#include <dcopobject.h>
+#include <dcopref.h>
+
+class XPartHost : public DCOPObject
+{
+ K_DCOP
+public:
+ XPartHost(QCString name) : DCOPObject(name) {}
+
+k_dcop:
+
+ /** The XPart should register itself to its host when it is created */
+ virtual DCOPRef registerXPart( const DCOPRef &part ) = 0;
+
+ /** Returns the registered part */
+ virtual DCOPRef part() = 0;
+
+ /** The XPart informs its host about its available actions.
+ * the actions are sent to the XPart using XPart::activateAction */
+ virtual ASYNC createActions( const QCString &xmlActions ) = 0;
+
+ /** DCOP signal emitted by the XPart and received here, to be
+ * forwarded to the KPartHost. See KParts documentation for
+ * more details. */
+ virtual ASYNC setWindowCaption( const QString &caption ) = 0;
+
+ /** DCOP signal emitted by the XPart and received here, to be
+ * forwarded to the KPartHost. See KParts documentation for
+ * more details. */
+ virtual ASYNC setStatusBarText( const QString &text ) = 0;
+
+
+ /** DCOP signal emitted by the XPart and received here, to be
+ * forwarded to the KPartHost. See KParts documentation for
+ * more details. */
+ virtual ASYNC started() = 0;
+
+ /** DCOP signal emitted by the XPart and received here, to be
+ * forwarded to the KPartHost. See KParts documentation for
+ * more details. */
+ virtual ASYNC completed() = 0;
+
+ /** DCOP signal emitted by the XPart and received here, to be
+ * forwarded to the KPartHost. See KParts documentation for
+ * more details. */
+ virtual ASYNC canceled( const QString &errMsg ) = 0;
+
+};
+
+#endif
diff --git a/xparts/src/interfaces/xpartmanager.h b/xparts/src/interfaces/xpartmanager.h
new file mode 100644
index 00000000..a172ee3f
--- /dev/null
+++ b/xparts/src/interfaces/xpartmanager.h
@@ -0,0 +1,20 @@
+#ifndef __xkparts_partmanager_h__
+#define __xkparts_partmanager_h__
+
+#include <dcopobject.h>
+#include <qglobal.h>
+
+class XKPartManager : public DCOPObject
+{
+ K_DCOP
+
+k_dcop:
+ /** Query a XPart able to handle a given mimetype */
+ virtual DCOPRef createPart( QString servicetype ) = 0;
+
+ /** Delete a previously created XPart */
+ virtual void deletePart( DCOPRef ref ) = 0;
+};
+
+
+#endif
diff --git a/xparts/src/kde/Makefile.am b/xparts/src/kde/Makefile.am
new file mode 100644
index 00000000..acdfff7f
--- /dev/null
+++ b/xparts/src/kde/Makefile.am
@@ -0,0 +1,17 @@
+
+INCLUDES = -I$(srcdir)/../interfaces $(all_includes)
+
+lib_LTLIBRARIES = libkdexparts.la
+
+libkdexparts_la_SOURCES = xparthost_kpart.cpp xparthost.skel xpart.stub \
+ kbrowsersignals.cpp xbrowsersignals.skel xbrowserextension.stub
+libkdexparts_la_LIBADD = $(LIB_KPARTS)
+libkdexparts_la_LDFLAGS = $(all_libraries) -no-undefined -version-info 1:0
+
+xpart_DIR=$(srcdir)/../interfaces
+xparthost_DIR=$(srcdir)/../interfaces
+xbrowsersignals_DIR=$(srcdir)/../interfaces
+xbrowserextension_DIR=$(srcdir)/../interfaces
+
+METASOURCES = AUTO
+
diff --git a/xparts/src/kde/kbrowsersignals.cpp b/xparts/src/kde/kbrowsersignals.cpp
new file mode 100644
index 00000000..f96655f0
--- /dev/null
+++ b/xparts/src/kde/kbrowsersignals.cpp
@@ -0,0 +1,31 @@
+#include "kbrowsersignals.h"
+#include "xparthost_kpart.h"
+#include "xbrowserextension_stub.h"
+#include <kurl.h>
+
+KBrowserSignals::KBrowserSignals( XPartHost_KPart *_part, DCOPRef extension )
+ : KParts::BrowserExtension( _part )
+{
+ qDebug("KBrowserSignals constructor");
+ part = _part;
+ ext = new XBrowserExtension_stub( extension.app(), extension.object() );
+ ext->setBrowserSignals( DCOPRef( this ) );
+}
+
+KBrowserSignals::~KBrowserSignals()
+{
+ delete ext;
+}
+
+void KBrowserSignals::openURLRequest( const QCString &url)
+{
+ KURL u = QString(url);
+ emit KParts::BrowserExtension::openURLRequest(u);
+}
+
+void KBrowserSignals::createNewWindow( const QCString &url )
+{
+}
+
+#include "kbrowsersignals.moc"
+
diff --git a/xparts/src/kde/kbrowsersignals.h b/xparts/src/kde/kbrowsersignals.h
new file mode 100644
index 00000000..dab8f208
--- /dev/null
+++ b/xparts/src/kde/kbrowsersignals.h
@@ -0,0 +1,27 @@
+#ifndef __kbrowsersignals_h__
+#define __kbrowsersignals_h__
+
+#include <xbrowsersignals.h>
+#include <kparts/browserextension.h>
+#include <dcopref.h>
+
+class XBrowserExtension_stub;
+class XPartHost_KPart;
+
+class KBrowserSignals : public KParts::BrowserExtension, virtual public XBrowserSignals
+{
+ Q_OBJECT
+public:
+ KBrowserSignals( XPartHost_KPart *part, DCOPRef ref );
+ virtual ~KBrowserSignals();
+
+
+ virtual ASYNC openURLRequest( const QCString &url);
+ virtual ASYNC createNewWindow( const QCString &url );
+
+protected:
+ XPartHost_KPart *part;
+ XBrowserExtension_stub *ext;
+};
+
+#endif
diff --git a/xparts/src/kde/xparthost_kpart.cpp b/xparts/src/kde/xparthost_kpart.cpp
new file mode 100644
index 00000000..c88e0c99
--- /dev/null
+++ b/xparts/src/kde/xparthost_kpart.cpp
@@ -0,0 +1,150 @@
+#include "xparthost_kpart.h"
+#include "kbrowsersignals.h"
+#include "xpart_stub.h"
+
+#include <dcopclient.h>
+#include <kapplication.h>
+
+#include <assert.h>
+
+#include <qxembed.h>
+
+#include <qdom.h>
+#include <kaction.h>
+
+#include <kdebug.h>
+
+XPartHost_KPart::XPartHost_KPart( QWidget *parentWidget, const char *widgetName,
+ QObject *parent, const char *name )
+ : KParts::ReadOnlyPart( parent, name ),
+ XPartHost("parthost")
+{
+ m_stub = 0;
+ be = 0;
+ embed = new QXEmbed(parentWidget, widgetName);
+ setWidget(embed);
+}
+
+XPartHost_KPart::~XPartHost_KPart()
+{
+ delete m_stub;
+}
+
+DCOPRef XPartHost_KPart::part()
+{
+ return m_part;
+}
+
+DCOPRef XPartHost_KPart::registerXPart( const DCOPRef &part )
+{
+ m_part = part;
+
+ assert( m_stub == 0 );
+
+ m_stub = new XPart_stub( part.app(), part.object() );
+
+ kdDebug() << "embedding window " << m_stub->windowId() << endl;
+ embed->embed( static_cast<WId>( m_stub->windowId() ) );
+
+ m_stub->show();
+ embed->show();
+ DCOPRef ref = m_stub->queryExtension("browserextension");
+ if( !ref.isNull() ) {
+ qDebug(" found browser extension ");
+ be = new KBrowserSignals( this, ref );
+ }
+ return DCOPRef( kapp->dcopClient()->appId(), objId() );
+}
+
+
+void XPartHost_KPart::createActions( const QCString &xmlActions )
+{
+ qDebug("--> createActions");
+ // creates a set of actions and adds them to the actionCollection
+ QDomDocument d;
+ d.setContent( xmlActions );
+
+ QDomElement docElem = d.documentElement();
+
+ kdDebug() << "docElement is " << docElem.tagName() << endl;
+
+ QDomNode n = docElem.firstChild();
+ while( !n.isNull() ) {
+ QDomElement e = n.toElement();
+ if( !e.isNull() ) {
+ if ( e.tagName() == "Action") {
+ QString name = e.attribute("name");
+ QString type = e.attribute("type");
+
+ if(type.isEmpty())
+ new KAction( name, 0, this, SLOT( actionActivated() ), actionCollection(), name.latin1() );
+ else if( type == "toggle" )
+ new KToggleAction( name, 0, this, SLOT( actionActivated() ), actionCollection(), name.latin1() );
+ kdDebug() << "action=" << name << " type=" << type << endl;
+ } else if ( e.tagName() == "XMLFile" ) {
+ QString location = e.attribute("location");
+ setXMLFile(location);
+ }
+ }
+ n = n.nextSibling();
+ }
+ emit actionsInitialized();
+}
+
+
+void XPartHost_KPart::setWindowCaption( const QString &caption )
+{
+ emit KParts::ReadOnlyPart::setWindowCaption( caption );
+}
+
+void XPartHost_KPart::setStatusBarText( const QString &text )
+{
+ emit KParts::ReadOnlyPart::setStatusBarText( text );
+}
+
+void XPartHost_KPart::started()
+{
+ emit KParts::ReadOnlyPart::started( 0 );
+}
+
+void XPartHost_KPart::completed()
+{
+ emit KParts::ReadOnlyPart::completed();
+}
+
+void XPartHost_KPart::canceled( const QString &errMsg )
+{
+ emit KParts::ReadOnlyPart::canceled( errMsg );
+}
+
+bool XPartHost_KPart::openURL( const KURL &url )
+{
+ qDebug("XPartHost_KPart::openUrl()");
+ return m_stub->openURL( url.url().latin1() );
+}
+
+bool XPartHost_KPart::closeURL()
+{
+ return m_stub->closeURL();
+}
+
+
+void XPartHost_KPart::actionActivated()
+{
+ const QObject *o = sender();
+
+ if( !o->inherits("KAction") ) return;
+
+ const KAction *action = static_cast<const KAction *>(o);
+ QString name = action->text();
+ int state = 0;
+
+ if(action->inherits("KToggleAction")) {
+ const KToggleAction *t = static_cast<const KToggleAction *>(action);
+ state = t->isChecked();
+ }
+
+ m_stub->activateAction(name, state);
+}
+
+#include "xparthost_kpart.moc"
diff --git a/xparts/src/kde/xparthost_kpart.h b/xparts/src/kde/xparthost_kpart.h
new file mode 100644
index 00000000..5a12dec0
--- /dev/null
+++ b/xparts/src/kde/xparthost_kpart.h
@@ -0,0 +1,74 @@
+#ifndef __xparthost_kpart_h__
+#define __xparthost_kpart_h__
+
+#include <xparthost.h>
+
+#include <kparts/part.h>
+
+class XPart_stub;
+class KBrowserSignals;
+class QXEmbed;
+
+
+/**
+ * This class is the middle class between the host of the KPart (usually a
+ * KParts::MainWindow) and the XPart. It transfer calls from the XPart to the
+ * KPartHost host and from the KPartHost to the XPart.
+ *
+ * Note : In the XPart white paper, this class is named KXPartHost
+ */
+class XPartHost_KPart : public KParts::ReadOnlyPart, public XPartHost
+{
+ Q_OBJECT
+public:
+ XPartHost_KPart( QWidget *parentWidget, const char *widgetName,
+ QObject *parent, const char *name );
+ virtual ~XPartHost_KPart();
+
+ // DCOP stuff
+
+ /** The XPart uses this function to register itself */
+ virtual DCOPRef registerXPart( const DCOPRef &part );
+
+ /** Return the XPart DCOPRef to someone willing to communicate with it */
+ virtual DCOPRef part();
+
+ // KPart signals
+
+ /** Emitted by the XPart, to be transfered to the KPart host */
+ virtual ASYNC createActions( const QCString &xmlActions );
+ /** Emitted by the XPart, to be transfered to the KPart host */
+ virtual ASYNC setWindowCaption( const QString &caption );
+ /** Emitted by the XPart, to be transfered to the KPart host */
+ virtual ASYNC setStatusBarText( const QString &text );
+
+ /** Emitted by the XPart, to be transfered to the KPart host */
+ virtual ASYNC started();
+ /** Emitted by the XPart, to be transfered to the KPart host */
+ virtual ASYNC completed();
+ /** Emitted by the XPart, to be transfered to the KPart host */
+ virtual ASYNC canceled( const QString &errMsg );
+
+ // reimplemented from KReadOnlyPart
+ /** function called by the KPart host to be forwarded to the XPart */
+ virtual bool openURL( const KURL &url );
+ /** function called by the KPart host to be forwarded to the XPart */
+ virtual bool closeURL();
+
+protected:
+ virtual bool openFile() { return false; }
+
+private slots:
+ void actionActivated();
+
+signals:
+ void actionsInitialized();
+
+private:
+ DCOPRef m_part;
+ XPart_stub *m_stub;
+ KBrowserSignals *be;
+ QXEmbed *embed;
+};
+
+#endif
diff --git a/xparts/xpart_notepad/Makefile.am b/xparts/xpart_notepad/Makefile.am
new file mode 100644
index 00000000..cadb799e
--- /dev/null
+++ b/xparts/xpart_notepad/Makefile.am
@@ -0,0 +1,29 @@
+INCLUDES = -I$(srcdir)/../src/kde -I$(srcdir)/../src/interfaces -I$(prefix)/include -I$(top_srcdir) $(all_includes)
+
+#AM_CFLAGS += $(GLIB_CFLAGS) $(GTK_CFLAGS)
+
+bin_PROGRAMS = xp_notepad shell_xparthost
+
+xpart_DIR=$(srcdir)/../src/interfaces
+xparthost_DIR=$(srcdir)/../src/interfaces
+
+xp_notepad_SOURCES = xp_notepad.cpp xpart.skel xparthost.stub
+xp_notepad_LDADD = ../src/kde/libkdexparts.la
+#xp_notepad_LDFLAGS = -L$(prefix)/lib -lxpcom $(all_libraries)
+xp_notepad_LDFLAGS = -L$(prefix)/lib $(all_libraries)
+
+shell_xparthost_SOURCES = shell_xparthost.cpp
+shell_xparthost_LDADD = $(top_builddir)/xparts/src/kde/libkdexparts.la
+shell_xparthost_LDFLAGS = $(all_libraries)
+
+lib_LTLIBRARIES = libxp_notepadpart.la
+
+libxp_notepadpart_la_SOURCES = xp_notepad_factory.cpp
+libxp_notepadpart_la_LDFLAGS = -module $(all_libraries)
+libxp_notepadpart_la_LIBADD = ../src/kde/libkdexparts.la
+
+servicedir = $(kde_servicesdir)
+service_DATA = xp_notepad.desktop
+
+METASOURCES = AUTO
+
diff --git a/xparts/xpart_notepad/README b/xparts/xpart_notepad/README
new file mode 100644
index 00000000..0d1ba65e
--- /dev/null
+++ b/xparts/xpart_notepad/README
@@ -0,0 +1,3 @@
+
+xpart_notepad is a small XPart editor. Use it to understand how to use XPart
+technology.
diff --git a/xparts/xpart_notepad/shell_xparthost.cpp b/xparts/xpart_notepad/shell_xparthost.cpp
new file mode 100644
index 00000000..bd6a9418
--- /dev/null
+++ b/xparts/xpart_notepad/shell_xparthost.cpp
@@ -0,0 +1,80 @@
+
+#include "xparthost_kpart.h"
+#include "shell_xparthost.h"
+
+#include <dcopclient.h>
+#include <dcopobject.h>
+#include <kapplication.h>
+#include <kstdaction.h>
+#include <kaction.h>
+#include <kmainwindow.h>
+#include <kprocess.h>
+#include <kparts/mainwindow.h>
+#include <kdebug.h>
+
+ShellWindow::ShellWindow()
+ : KParts::MainWindow()
+{
+ m_host = new XPartHost_KPart( this, 0, this, "parthost" );
+
+ setCentralWidget( m_host->widget() );
+
+ connect(m_host, SIGNAL( actionsInitialized() ), this, SLOT( mergeGUI() ) );
+
+ // Launch our XPart child.
+ m_partProcess = new KProcess;
+ *m_partProcess << "./xp_notepad"
+ << kapp->dcopClient()->appId() << m_host->objId();
+ m_partProcess->start();
+
+ // Init our Gui
+ (void) new KAction( "Hop", 0, this, SLOT(hop()), actionCollection(), "hop" );
+ KStdAction::quit( this, SLOT( close() ), actionCollection() );
+ KSelectAction *s = new KSelectAction( "http://www.kde.org" , 0,
+ actionCollection(), "location" );
+ connect( s, SIGNAL(activated( const QString& ) ), this, SLOT( slotOpenUrl( const QString & ) ) );
+ s->setEditable(true);
+
+ kdDebug() << "KShell window created" << endl;
+}
+
+ShellWindow::~ShellWindow()
+{
+ delete m_partProcess;
+}
+
+void ShellWindow::hop()
+{
+ kdDebug() << "hop called!" << endl;
+}
+
+void ShellWindow::slotOpenUrl( const QString &url )
+{
+ kdDebug() << "this=" << this;
+ kdDebug() << "url=" << url << endl;
+ m_host->openURL(url.latin1());
+}
+
+void ShellWindow::mergeGUI()
+{
+ qDebug("initGUI");
+ setXMLFile("shell_xparthost.rc");
+ createGUI( m_host );
+ m_host->widget()->setFocus();
+ kdDebug() << "focus set to embedded widget" << endl;
+}
+
+int main( int argc, char **argv )
+{
+ KApplication app( argc, argv, "xparthost_shell" );
+
+ app.dcopClient()->registerAs("xparthost_shell");
+
+ ShellWindow *w = new ShellWindow;
+ w->resize(500, 500);
+ w->show();
+
+ return app.exec();
+}
+
+#include "shell_xparthost.moc"
diff --git a/xparts/xpart_notepad/shell_xparthost.h b/xparts/xpart_notepad/shell_xparthost.h
new file mode 100644
index 00000000..02982326
--- /dev/null
+++ b/xparts/xpart_notepad/shell_xparthost.h
@@ -0,0 +1,29 @@
+#ifndef shell_xparthost_h
+#define shell_xparthost_h
+
+#include <kmainwindow.h>
+#include <kparts/mainwindow.h>
+#include <kdebug.h>
+
+class KProcess;
+
+class ShellWindow : public KParts::MainWindow
+{
+ Q_OBJECT
+
+public:
+ ShellWindow();
+ virtual ~ShellWindow();
+
+public slots:
+ void hop();
+
+ void slotOpenUrl( const QString &url );
+ void mergeGUI();
+
+private:
+ XPartHost_KPart *m_host;
+ KProcess *m_partProcess;
+};
+
+#endif
diff --git a/xparts/xpart_notepad/shell_xparthost.rc b/xparts/xpart_notepad/shell_xparthost.rc
new file mode 100644
index 00000000..8164b5b4
--- /dev/null
+++ b/xparts/xpart_notepad/shell_xparthost.rc
@@ -0,0 +1,11 @@
+<!DOCTYPE kpartgui SYSTEM "kpartgui.dtd">
+<kpartgui name="xparthost_shell" version="1">
+
+<MenuBar>
+ <Menu name="File">
+ <Merge/>
+ </Menu>
+ <Merge/>
+</MenuBar>
+
+</kpartgui>
diff --git a/xparts/xpart_notepad/xp_notepad.cpp b/xparts/xpart_notepad/xp_notepad.cpp
new file mode 100644
index 00000000..57173bbb
--- /dev/null
+++ b/xparts/xpart_notepad/xp_notepad.cpp
@@ -0,0 +1,114 @@
+#include <dcopclient.h>
+#include <kapplication.h>
+#include <qmultilineedit.h>
+#include <qfile.h>
+#include <qtextstream.h>
+#include <stdio.h>
+#include <iostream.h>
+#include <xpart.h>
+#include <kdebug.h>
+
+#include "xparthost_stub.h"
+
+class XPartNotepad : public QMultiLineEdit, virtual public XPart
+{
+
+public:
+ XPartNotepad(char *)
+ {
+ setText("This is a xpart component editor");
+ setReadOnly( false );
+ resize( 200, 200 );
+ QMultiLineEdit::setFocus();
+ }
+
+ /** needed by XPartManager to embed the part */
+ Q_UINT32 windowId()
+ { return winId(); }
+
+ /** used by XPartManager to show the part */
+ void show()
+ { printf("show()\n"); QWidget::show(); }
+
+ /** sent by the XPartHost to query an url */
+ bool openURL( const QCString& url )
+ { printf("openURL %s\n", (const char *) url );
+ QFile f(url);
+ QString s;
+ if ( ! f.open(IO_ReadOnly) ) {
+ return false;
+ }
+ QTextStream t( &f );
+ while ( !t.eof() ) {
+ s += t.readLine() + "\n";
+ }
+ f.close();
+ setText(s);
+ return true;
+ }
+
+ /** sent by the XPartHost to close an url */
+ bool closeURL()
+ { printf("closeURL\n"); setText(""); return true; }
+
+ /** called when an action has been activated. name is
+ * the name of the
+ * * action, state is used with Toggle actions to
+ * precise the current state.
+ * */
+ void activateAction( const QString &name, int state )
+ { printf("activateAction: %s, %d\n", name.latin1(), state ); }
+
+ /** are extentions available -> browser extension
+ * / TextEditor ? */
+ DCOPRef queryExtension( const QCString& extension )
+ { printf("query Extension : %s\n", (const char * ) extension ); return DCOPRef(); }
+
+
+protected:
+ void focusInEvent( QFocusEvent * )
+ { kdDebug() << "Focus in" << endl; QMultiLineEdit::setFocus(); }
+ void focusOutEvent( QFocusEvent * )
+ { kdDebug() << "Focus Out" << endl;QMultiLineEdit::setFocus(); }
+};
+
+int main( int argc, char **argv )
+{
+ if (argc < 3) {
+ printf("application need arguments");
+ return 1;
+ }
+ printf("args: XPartHost appId = %s , XPartHost_KPart objId = %s\n", argv[1], argv[2] );
+
+ KApplication app( argc, argv, "xp_notepad" );
+ XPartNotepad * xpn = new XPartNotepad("xp_notepad");
+ app.setMainWidget( xpn );
+ app.dcopClient()->attach();
+ QCString appId = app.dcopClient()->registerAs("xp_notepad", true);
+
+ XPartHost_stub xph_stub( argv[1], argv[2] );
+ DCOPRef xpn_dcopref( xpn );
+
+ DCOPRef xph_dcopref = xph_stub.registerXPart(xpn_dcopref);
+ if ( xph_dcopref.isNull() ) {
+ printf("could not register\n");
+ return 2;
+ }
+ printf("XPart registered!\n");
+
+ // Initializing actions:
+ const char * actions =
+"<!DOCTYPE actionList SYSTEM \"actionlist.dtd\">\n"
+"<Actionlist>\n"
+" <Action name=\"open_url\" />\n"
+" <Action name=\"close_url\" />\n"
+" <Action name=\"nonexistant\" />\n"
+" <XMLFile location=\"./xp_notepad.rc\" />\n"
+"</Actionlist>\n";
+ xph_stub.createActions( actions );
+
+ return app.exec();
+}
+
+
+
diff --git a/xparts/xpart_notepad/xp_notepad.desktop b/xparts/xpart_notepad/xp_notepad.desktop
new file mode 100644
index 00000000..bda514ed
--- /dev/null
+++ b/xparts/xpart_notepad/xp_notepad.desktop
@@ -0,0 +1,9 @@
+[Desktop Entry]
+Type=Service
+Exec=foobar
+Comment=XPart Notepad Editor
+Icon=
+Name=XNotepad (XPart example)
+MimeType=text/english;text/plain;text/x-makefile;text/x-c++hdr;text/x-c++src;text/x-chdr;text/x-csrc;text/x-java;text/x-moc;text/x-pascal;text/x-tcl;text/x-tex;application/x-shellscript;text/x-c;text/x-c++;text/x-diff;
+ServiceTypes=KParts/ReadOnlyPart
+X-KDE-Library=libxp_notepadpart
diff --git a/xparts/xpart_notepad/xp_notepad.rc b/xparts/xpart_notepad/xp_notepad.rc
new file mode 100644
index 00000000..13428980
--- /dev/null
+++ b/xparts/xpart_notepad/xp_notepad.rc
@@ -0,0 +1,11 @@
+<!DOCTYPE kpartgui SYSTEM "kpartgui.dtd">
+<kpartgui name="notepad_xpart" version="1">
+<MenuBar>
+ <Menu name="File">
+ <Action name="open_url" />
+ <Action name="close_url" />
+ <Separator />
+ <Action name="nonexistant" />
+ </Menu>
+</MenuBar>
+</kpartgui>
diff --git a/xparts/xpart_notepad/xp_notepad_factory.cpp b/xparts/xpart_notepad/xp_notepad_factory.cpp
new file mode 100644
index 00000000..232e5756
--- /dev/null
+++ b/xparts/xpart_notepad/xp_notepad_factory.cpp
@@ -0,0 +1,72 @@
+/* This file is part of the KDE project
+ *
+ * Copyright (C) 2000 Simon Hausmann <hausmann@kde.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include <dcopclient.h>
+#include <dcopobject.h>
+#include <kapplication.h>
+#include <kstdaction.h>
+#include <kaction.h>
+#include <kmainwindow.h>
+#include <kprocess.h>
+#include <kparts/mainwindow.h>
+#include <kdebug.h>
+#include "xp_notepad_factory.h"
+
+extern "C"
+{
+ void *init_libxp_notepadpart()
+ {
+ return new XP_NotepadFactory( true );
+ }
+};
+
+
+KParts::Part *XP_NotepadFactory::createPartObject( QWidget *parentWidget, const char *widgetName, QObject *parent, const char *name, const char *className, const QStringList & )
+{
+ return new XP_NotepadPart( parentWidget, widgetName, parent, name );
+}
+
+XP_NotepadPart::XP_NotepadPart(QWidget *parentWidget, const char *widgetName,
+ QObject *parent, const char *name)
+ : XPartHost_KPart(parentWidget, widgetName, parent, name)
+{
+ m_partProcess = new KProcess;
+ *m_partProcess << "xnotepard"
+ << kapp->dcopClient()->appId() << objId();
+ m_partProcess->start();
+
+ qDebug("---->>>>>> enter loop");
+ kapp->enter_loop();
+ qDebug("----<<<<<< left loop");
+}
+
+XP_NotepadPart::~XP_NotepadPart()
+{
+ delete m_partProcess;
+}
+
+void XP_NotepadPart::createActions( const QCString &xmlActions )
+{
+ XPartHost_KPart::createActions( xmlActions );
+ qDebug("----<<<<<< exit loop");
+ kapp->exit_loop();
+}
+
+#include "xp_notepad_factory.moc"
diff --git a/xparts/xpart_notepad/xp_notepad_factory.h b/xparts/xpart_notepad/xp_notepad_factory.h
new file mode 100644
index 00000000..efc812fd
--- /dev/null
+++ b/xparts/xpart_notepad/xp_notepad_factory.h
@@ -0,0 +1,62 @@
+/* This file is part of the KDE project
+ *
+ * Copyright (C) 2000 Simon Hausmann <hausmann@kde.org>
+ * Copyright (C) 2001 Philippe Fremy <pfremy@chez.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+#ifndef __xp_notepad_factory_h__
+#define __xp_notepad_factory_h__
+
+#include <kparts/factory.h>
+#include <qptrlist.h>
+#include <kurl.h>
+#include "xparthost_kpart.h"
+
+class KInstance;
+class KAboutData;
+class KHTMLSettings;
+class KHTMLPart;
+class KProcess;
+
+class XP_NotepadFactory : public KParts::Factory
+{
+ Q_OBJECT
+public:
+ XP_NotepadFactory( bool clone = false ) {}
+ virtual ~XP_NotepadFactory() {}
+
+ virtual KParts::Part *createPartObject( QWidget *parentWidget, const char *widgetName, QObject *parent, const char *name, const char *className, const QStringList &args );
+
+};
+
+
+
+class XP_NotepadPart : public XPartHost_KPart
+{
+ Q_OBJECT
+
+public:
+ XP_NotepadPart(QWidget *parentWidget, const char *widgetName,
+ QObject *parent, const char *name);
+ virtual ~XP_NotepadPart();
+
+ virtual void createActions( const QCString &xmlActions );
+private:
+ KProcess *m_partProcess;
+};
+
+#endif