Copy the KDE 3.5 branch to branches/trinity for new KDE 3.5 features.
BUG:215923 git-svn-id: svn://anonsvn.kde.org/home/kde/branches/trinity/kdebindings@1054174 283d02a7-25f6-0310-bc7c-ecb5cbfe19dav3.5.13-sru
commit
90825e2392
@ -0,0 +1,6 @@
|
||||
DCOP C Bindings: - DCOP protocol and C++ implementation by
|
||||
Matthias Ettrich <ettrich@kde.org>
|
||||
Preston Brown <pbrown@kde.org>
|
||||
Waldo Bastian <bastian@kde.org>
|
||||
- C bindings by Simon Hausmann <simon@kde.org>
|
||||
port to GtkObject by Lars Knoll <knoll@kde.org>
|
@ -0,0 +1,27 @@
|
||||
2004-06-27 Richard Dale <Richard_Dale@tipitina.demon.co.uk>
|
||||
|
||||
* The qtruby and korundum ruby bindings are built by default
|
||||
* Both Qt only and Qt/KDE versions of the Smoke library are built
|
||||
|
||||
2002-11-05 Marcus Urban <murban@mylinuxisp.com>
|
||||
* Match changes made in KDE's RGBColor class in kdec, kdejava
|
||||
* Various changes in qtc and qtjava to match changes in Qt 3.1
|
||||
|
||||
2002-04-12 Richard Dale <duke@tipitina.demon.co.uk>
|
||||
|
||||
* qtobjc is now built before kdeobjc
|
||||
|
||||
2002-04-12 Richard Dale <duke@tipitina.demon.co.uk>
|
||||
* added some extra Objective-C macro initialisation
|
||||
* kdec is now built by default
|
||||
2001-11-16 Richard Dale <duke@tipitina.demon.co.uk
|
||||
* added kalyptus - kdoc derived bindings generator for
|
||||
C/Objective-C/Java. Initial checkin.
|
||||
2001-11-15 Richard Dale <duke@tipitina.demon.co.uk
|
||||
* added Qt 3 beta6/KDE 3 alpha1/GNUstep Foundation Kit
|
||||
Objective-C bindings
|
||||
2001-10-22 Richard Dale <duke@tipitina.demon.co.uk
|
||||
* added Qt 3 beta6/KDE 3 alpha1 C bindings
|
||||
2000-11-06 Simon Hausmann <simon@kde.org>
|
||||
* added dcop c bindings
|
||||
|
@ -0,0 +1,176 @@
|
||||
Basic Installation
|
||||
==================
|
||||
|
||||
These are generic installation instructions.
|
||||
|
||||
The `configure' shell script attempts to guess correct values for
|
||||
various system-dependent variables used during compilation. It uses
|
||||
those values to create a `Makefile' in each directory of the package.
|
||||
It may also create one or more `.h' files containing system-dependent
|
||||
definitions. Finally, it creates a shell script `config.status' that
|
||||
you can run in the future to recreate the current configuration, a file
|
||||
`config.cache' that saves the results of its tests to speed up
|
||||
reconfiguring, and a file `config.log' containing compiler output
|
||||
(useful mainly for debugging `configure').
|
||||
|
||||
If you need to do unusual things to compile the package, please try
|
||||
to figure out how `configure' could check whether to do them, and mail
|
||||
diffs or instructions to the address given in the `README' so they can
|
||||
be considered for the next release. If at some point `config.cache'
|
||||
contains results you don't want to keep, you may remove or edit it.
|
||||
|
||||
The file `configure.in' is used to create `configure' by a program
|
||||
called `autoconf'. You only need `configure.in' if you want to change
|
||||
it or regenerate `configure' using a newer version of `autoconf'.
|
||||
|
||||
The simplest way to compile this package is:
|
||||
|
||||
1. `cd' to the directory containing the package's source code and type
|
||||
`./configure' to configure the package for your system. If you're
|
||||
using `csh' on an old version of System V, you might need to type
|
||||
`sh ./configure' instead to prevent `csh' from trying to execute
|
||||
`configure' itself.
|
||||
|
||||
Running `configure' takes a while. While running, it prints some
|
||||
messages telling which features it is checking for.
|
||||
|
||||
2. Type `make' to compile the package.
|
||||
|
||||
3. Optionally, type `make check' to run any self-tests that come with
|
||||
the package.
|
||||
|
||||
4. Type `make install' to install the programs and any data files and
|
||||
documentation.
|
||||
|
||||
5. You can remove the program binaries and object files from the
|
||||
source code directory by typing `make clean'. To also remove the
|
||||
files that `configure' created (so you can compile the package for
|
||||
a different kind of computer), type `make distclean'. There is
|
||||
also a `make maintainer-clean' target, but that is intended mainly
|
||||
for the package's developers. If you use it, you may have to get
|
||||
all sorts of other programs in order to regenerate files that came
|
||||
with the distribution.
|
||||
|
||||
Compilers and Options
|
||||
=====================
|
||||
|
||||
Some systems require unusual options for compilation or linking that
|
||||
the `configure' script does not know about. You can give `configure'
|
||||
initial values for variables by setting them in the environment. Using
|
||||
a Bourne-compatible shell, you can do that on the command line like
|
||||
this:
|
||||
CC=c89 CFLAGS=-O2 LIBS=-lposix ./configure
|
||||
|
||||
Or on systems that have the `env' program, you can do it like this:
|
||||
env CPPFLAGS=-I/usr/local/include LDFLAGS=-s ./configure
|
||||
|
||||
Compiling For Multiple Architectures
|
||||
====================================
|
||||
|
||||
You can compile the package for more than one kind of computer at the
|
||||
same time, by placing the object files for each architecture in their
|
||||
own directory. To do this, you must use a version of `make' that
|
||||
supports the `VPATH' variable, such as GNU `make'. `cd' to the
|
||||
directory where you want the object files and executables to go and run
|
||||
the `configure' script. `configure' automatically checks for the
|
||||
source code in the directory that `configure' is in and in `..'.
|
||||
|
||||
If you have to use a `make' that does not supports the `VPATH'
|
||||
variable, you have to compile the package for one architecture at a time
|
||||
in the source code directory. After you have installed the package for
|
||||
one architecture, use `make distclean' before reconfiguring for another
|
||||
architecture.
|
||||
|
||||
Installation Names
|
||||
==================
|
||||
|
||||
By default, `make install' will install the package's files in
|
||||
`/usr/local/kde/bin', `/usr/local/kde/lib', etc. You can specify an
|
||||
installation prefix other than `/usr/local/kde' by giving `configure'
|
||||
the option `--prefix=PATH'.
|
||||
|
||||
You can specify separate installation prefixes for
|
||||
architecture-specific files and architecture-independent files. If you
|
||||
give `configure' the option `--exec-prefix=PATH', the package will use
|
||||
PATH as the prefix for installing programs and libraries.
|
||||
Documentation and other data files will still use the regular prefix.
|
||||
|
||||
If the package supports it, you can cause programs to be installed
|
||||
with an extra prefix or suffix on their names by giving `configure' the
|
||||
option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'.
|
||||
|
||||
Optional Features
|
||||
=================
|
||||
|
||||
Some packages pay attention to `--enable-FEATURE' options to
|
||||
`configure', where FEATURE indicates an optional part of the package.
|
||||
They may also pay attention to `--with-PACKAGE' options, where PACKAGE
|
||||
is something like `gnu-as' or `x' (for the X Window System). The
|
||||
`README' should mention any `--enable-' and `--with-' options that the
|
||||
package recognizes.
|
||||
|
||||
For packages that use the X Window System, `configure' can usually
|
||||
find the X include and library files automatically, but if it doesn't,
|
||||
you can use the `configure' options `--x-includes=DIR' and
|
||||
`--x-libraries=DIR' to specify their locations.
|
||||
|
||||
Specifying the System Type
|
||||
==========================
|
||||
|
||||
There may be some features `configure' can not figure out
|
||||
automatically, but needs to determine by the type of host the package
|
||||
will run on. Usually `configure' can figure that out, but if it prints
|
||||
a message saying it can not guess the host type, give it the
|
||||
`--host=TYPE' option. TYPE can either be a short name for the system
|
||||
type, such as `sun4', or a canonical name with three fields:
|
||||
CPU-COMPANY-SYSTEM
|
||||
|
||||
See the file `config.sub' for the possible values of each field. If
|
||||
`config.sub' isn't included in this package, then this package doesn't
|
||||
need to know the host type.
|
||||
|
||||
If you are building compiler tools for cross-compiling, you can also
|
||||
use the `--target=TYPE' option to select the type of system they will
|
||||
produce code for and the `--build=TYPE' option to select the type of
|
||||
system on which you are compiling the package.
|
||||
|
||||
Sharing Defaults
|
||||
================
|
||||
|
||||
If you want to set default values for `configure' scripts to share,
|
||||
you can create a site shell script called `config.site' that gives
|
||||
default values for variables like `CC', `cache_file', and `prefix'.
|
||||
`configure' looks for `PREFIX/share/config.site' if it exists, then
|
||||
`PREFIX/etc/config.site' if it exists. Or, you can set the
|
||||
`CONFIG_SITE' environment variable to the location of the site script.
|
||||
A warning: not all `configure' scripts look for a site script.
|
||||
|
||||
Operation Controls
|
||||
==================
|
||||
|
||||
`configure' recognizes the following options to control how it
|
||||
operates.
|
||||
|
||||
`--cache-file=FILE'
|
||||
Use and save the results of the tests in FILE instead of
|
||||
`./config.cache'. Set FILE to `/dev/null' to disable caching, for
|
||||
debugging `configure'.
|
||||
|
||||
`--help'
|
||||
Print a summary of the options to `configure', and exit.
|
||||
|
||||
`--quiet'
|
||||
`--silent'
|
||||
`-q'
|
||||
Do not print messages saying which checks are being made.
|
||||
|
||||
`--srcdir=DIR'
|
||||
Look for the package's source code in directory DIR. Usually
|
||||
`configure' can determine that directory automatically.
|
||||
|
||||
`--version'
|
||||
Print the version of Autoconf used to generate the `configure'
|
||||
script, and exit.
|
||||
|
||||
`configure' also accepts some other, not widely useful, options.
|
||||
|
@ -0,0 +1,22 @@
|
||||
## kdebindings/Makefile.am
|
||||
## (C) 1997 Stephan Kulow
|
||||
|
||||
COMPILE_BEFORE_kdejava = qtjava
|
||||
COMPILE_BEFORE_kdec = qtc
|
||||
COMPILE_BEFORE_xparts = dcopc
|
||||
|
||||
# below if for proper korundum / qtruby build order
|
||||
COMPILE_BEFORE_qtruby = smoke
|
||||
COMPILE_BEFORE_korundum = qtruby
|
||||
|
||||
# the below is for proper referencing of dcopperl into SUBDIRS
|
||||
COMPILE_BEFORE_dcopc = dcopperl
|
||||
|
||||
AUTOMAKE_OPTIONS = foreign 1.6.1
|
||||
|
||||
$(top_srcdir)/acinclude.m4: $(top_srcdir)/dcopc/glib.m4 $(top_srcdir)/dcopc/gtk.m4
|
||||
|
||||
EXTRA_DIST = admin
|
||||
|
||||
include admin/deps.am
|
||||
|
@ -0,0 +1,15 @@
|
||||
|
||||
all:
|
||||
@echo "This Makefile is only for the CVS repository"
|
||||
@echo "This will be deleted before making the distribution"
|
||||
@echo ""
|
||||
@if test ! -d admin; then \
|
||||
echo "Please recheckout this module!" ;\
|
||||
echo "for cvs: use checkout once and after that update again" ;\
|
||||
echo "for cvsup: checkout kde-common from cvsup and" ;\
|
||||
echo " link kde-common/admin to ./admin" ;\
|
||||
exit 1 ;\
|
||||
fi
|
||||
$(MAKE) -f admin/Makefile.common cvs
|
||||
|
||||
.SILENT:
|
@ -0,0 +1,37 @@
|
||||
In this file:
|
||||
|
||||
* Notes for end users
|
||||
* Notes for developers
|
||||
|
||||
Notes for end users
|
||||
-------------------
|
||||
|
||||
You only need this package when something else requires it.
|
||||
|
||||
Notes for developers
|
||||
--------------------
|
||||
|
||||
This package contains:
|
||||
+ working:
|
||||
* dcopperl: DCOP bindings for Perl
|
||||
* kjsembed: javascript scripting support library for KDE applications
|
||||
* kdejava: KDE bindings for Java JNI to use Qt/KDE classes with Java
|
||||
* korundum: KDE bindings for ruby
|
||||
* python: a copy of SIP/pyQt/pyKDE bindings from riverbankcomputing.co.uk
|
||||
* qtjava: Qt bindings for Java JNI to use Qt/KDE classes with Java
|
||||
* qtruby: Qt bindings for Ruby
|
||||
* smoke: Language independent library for Qt and KDE bindings. Used by QtRuby
|
||||
and PerlQt.
|
||||
* kalyptus: a header parser and bindings generator for Qt/KDE. Used for
|
||||
Smoke, Java, C# and KSVG bindings generation at present.
|
||||
* dcoppython: DCOP bindings for Python
|
||||
|
||||
+ possibly broken:
|
||||
* dcopc: DCOP bindings for C
|
||||
* dcopjava: DCOP bindings for JAVA
|
||||
* xparts: allows you to embed non-KDE apps as a KPart
|
||||
|
||||
+ broken:
|
||||
* qtsharp: C# bindings for Qt (badly broken after qtc removal)
|
||||
|
||||
|
@ -0,0 +1,43 @@
|
||||
dnl put here things which have to be done as very last part of configure
|
||||
|
||||
all_tests=fine
|
||||
|
||||
if test -z "$CSC_NAME"; then
|
||||
echo ""
|
||||
echo "A C# compiler wasn't found. The Qt# bindings need either Mono, Portable.NET or Rotor."
|
||||
echo "You will need three things to compile the Qt# bindings:"
|
||||
echo ""
|
||||
echo "1. A C# compiler -- Mono's mcs, DotGNU/Portable.NET's cscc, or Rotors csc."
|
||||
echo ""
|
||||
echo "2. A CLR JIT. Mono's works the best right now. Qt# will work somewhat with"
|
||||
echo "DotGNU/Portable.NET's ilrun and with Rotor's JIT."
|
||||
echo ""
|
||||
echo "3. Portable.NET's csant tool. This is a Java ANT like build tool for C#"
|
||||
echo "programs. You can find these tools at the following locations:"
|
||||
echo ""
|
||||
echo "http://www.southern-storm.com.au/portable_net.html"
|
||||
echo "http://go-mono.org"
|
||||
echo "http://msdn.microsoft.com/downloads/default.asp?url=/downloads/topic.asp?URL=/MSDN-FILES/028/000/123/topic.xml"
|
||||
all_tests=bad
|
||||
fi
|
||||
|
||||
if test "x$kde_cv_java_bindir" = "xno"; then
|
||||
echo ""
|
||||
echo "Java wasn't found. The Java bindings need javac, javah and jni."
|
||||
echo "Try using --with-java=/your/java/dir. Typing 'make' now will skip the java bindings."
|
||||
echo ""
|
||||
all_tests=bad
|
||||
fi
|
||||
|
||||
if test -z "$LIBPYTHON" || test -z "$PYTHONINC"; then
|
||||
echo ""
|
||||
echo "Python or it's development files were not found. Qt and KDE bindings for Python will not be built."
|
||||
echo ""
|
||||
all_tests=bad
|
||||
fi
|
||||
|
||||
if test "$all_tests" = "fine"; then
|
||||
echo ""
|
||||
echo "Good - your configure finished. Start make now"
|
||||
echo ""
|
||||
fi
|
@ -0,0 +1,305 @@
|
||||
#MIN_CONFIG
|
||||
|
||||
# Check for ECMA-335 image loader.
|
||||
|
||||
AC_DEFUN([KDE_CHECK_CLI],[
|
||||
AC_ARG_WITH(cli, [ --with-cli=FILE ECMA 335 PE image loader is FILE ],
|
||||
[
|
||||
AC_MSG_CHECKING(for CLI image loader)
|
||||
|
||||
if test -x "$with_cli"
|
||||
then
|
||||
CLI="$with_cli"
|
||||
AC_MSG_RESULT($CLI)
|
||||
fi
|
||||
],
|
||||
[
|
||||
AC_PATH_PROG(CLI, mono, [], $PATH:/usr/local/bin)
|
||||
|
||||
if test -z "$CLI"
|
||||
then
|
||||
AC_PATH_PROG(CLI, ilrun, [], $PATH:/usr/local/bin)
|
||||
fi
|
||||
|
||||
if test -z "$CLI"
|
||||
then
|
||||
AC_PATH_PROG(CLI, clix, [], $PATH:/usr/local/bin)
|
||||
fi
|
||||
])
|
||||
|
||||
AC_SUBST(CLI)
|
||||
])
|
||||
|
||||
# Pick a C# compiler.
|
||||
|
||||
# Check for Portable.NET's C# compiler
|
||||
|
||||
AC_DEFUN([KDE_CHECK_CSCC],[
|
||||
AC_ARG_WITH(cscc, [ --with-cscc=FILE cscc executable is FILE ],
|
||||
[
|
||||
AC_MSG_CHECKING(for $with_cscc)
|
||||
|
||||
if test -x $with_cscc
|
||||
then
|
||||
AC_MSG_RESULT(found)
|
||||
cscc="$with_cscc"
|
||||
else
|
||||
AC_MSG_RESULT(no)
|
||||
fi
|
||||
],
|
||||
[
|
||||
AC_PATH_PROG(cscc, cscc, [], $PATH:/usr/local/bin)
|
||||
])
|
||||
])
|
||||
|
||||
# Check for Microsoft's C# compiler
|
||||
|
||||
AC_DEFUN([KDE_CHECK_CSC],[
|
||||
AC_ARG_WITH(csc, [ --with-csc=FILE csc executable is FILE ],
|
||||
[
|
||||
AC_MSG_CHECKING(for $with_csc)
|
||||
|
||||
if test -x $with_csc
|
||||
then
|
||||
AC_MSG_RESULT(found)
|
||||
csc="$with_csc"
|
||||
else
|
||||
AC_MSG_RESULT(no)
|
||||
fi
|
||||
],
|
||||
[
|
||||
AC_PATH_PROG(csc, csc.exe, [], $PATH:/usr/local/bin)
|
||||
|
||||
if test -z "$csc"
|
||||
then
|
||||
AC_PATH_PROG(csc, csc, [], $PATH:/usr/local/bin)
|
||||
fi
|
||||
])
|
||||
])
|
||||
|
||||
# Check for Mono's C# compiler
|
||||
|
||||
AC_DEFUN([KDE_CHECK_MCS],[
|
||||
dnl AC_REQUIRE(KDE_CHECK_CLI)
|
||||
AC_ARG_WITH(mcs, [ --with-mcs=FILE mcs executable is FILE ],
|
||||
[
|
||||
AC_MSG_CHECKING(for $with_mcs)
|
||||
|
||||
if test -f $with_mcs
|
||||
then
|
||||
AC_MSG_RESULT(found)
|
||||
mcs="$with_mcs"
|
||||
else
|
||||
AC_MSG_RESULT(no)
|
||||
fi
|
||||
],
|
||||
[
|
||||
AC_PATH_PROG(mcs, mcs, [], $PATH:/usr/local/bin)
|
||||
|
||||
if test -z "$mcs"
|
||||
then
|
||||
AC_PATH_PROG(mcs, mcs.exe, [], $PATH:/usr/local/bin)
|
||||
fi
|
||||
])
|
||||
|
||||
])
|
||||
|
||||
AM_PATH_GLIB([1.2.6])
|
||||
AM_PATH_GTK([1.2.6])
|
||||
|
||||
# check for CSANT compiler
|
||||
|
||||
AC_DEFUN([KDE_CHECK_CSANT],[
|
||||
])
|
||||
|
||||
# Pick one of the available C# compilers.
|
||||
|
||||
AC_DEFUN([KDE_CHECK_CS_COMPILER],[
|
||||
KDE_CHECK_CSANT
|
||||
KDE_CHECK_CSCC
|
||||
KDE_CHECK_CSC
|
||||
KDE_CHECK_MCS
|
||||
|
||||
AC_MSG_CHECKING(for c-sharp compiler)
|
||||
|
||||
AC_ARG_WITH(cs-compiler, [ --with-cs-compiler=NAME mcs, cscc, or csc ],
|
||||
[
|
||||
if test "$with_cs_compiler" = "cscc"
|
||||
then
|
||||
CSC="$cscc"
|
||||
CSC_NAME="cscc"
|
||||
fi
|
||||
|
||||
if test "$with_cs_compiler" = "csc"
|
||||
then
|
||||
CSC="$csc"
|
||||
CSC_NAME="csc"
|
||||
fi
|
||||
|
||||
if test "$with_cs_compiler" = "mcs"
|
||||
then
|
||||
CSC="$mono"
|
||||
CSC_NAME="mcs"
|
||||
fi
|
||||
|
||||
if test -z "$CSC_NAME"
|
||||
then
|
||||
AC_MSG_RESULT(no)
|
||||
echo "ERROR: Unknown C# compiler: $with_cs_compiler"
|
||||
exit
|
||||
else
|
||||
AC_MSG_RESULT($CSC_NAME)
|
||||
fi
|
||||
],
|
||||
[
|
||||
if test -n "$mcs"
|
||||
then
|
||||
CSC="$mcs"
|
||||
CSC_NAME="mcs"
|
||||
AC_MSG_RESULT(mcs)
|
||||
else
|
||||
if test -n "$cscc"
|
||||
then
|
||||
CSC="$cscc"
|
||||
CSC_NAME="cscc"
|
||||
AC_MSG_RESULT(cscc)
|
||||
else
|
||||
if test -n "$csc"
|
||||
then
|
||||
CSC="$csc"
|
||||
CSC_NAME="csc"
|
||||
AC_MSG_RESULT(csc)
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
if test -z "$CSC_NAME"
|
||||
then
|
||||
AC_MSG_RESULT(no)
|
||||
DO_NOT_COMPILE="$DO_NOT_COMPILE qtsharp"
|
||||
fi
|
||||
])
|
||||
|
||||
AC_SUBST(CSC)
|
||||
AC_SUBST(CSC_NAME)
|
||||
])
|
||||
|
||||
dnl
|
||||
dnl Java checks
|
||||
dnl
|
||||
|
||||
AC_DEFUN([KDE_CHECK_JAVA],
|
||||
[
|
||||
AC_REQUIRE([KDE_CHECK_JAVA_DIR])
|
||||
if test "$kde_java_bindir" = "no"; then
|
||||
DO_NOT_COMPILE="$DO_NOT_COMPILE $1";
|
||||
fi
|
||||
]
|
||||
)
|
||||
|
||||
dnl
|
||||
dnl Check Perl
|
||||
dnl
|
||||
|
||||
AC_DEFUN([KDE_CHECK_PERL],
|
||||
[
|
||||
AC_ARG_VAR(PERL, full path to the perl program)
|
||||
AC_PATH_PROG(PERL, perl, "perl")
|
||||
AC_MSG_CHECKING([for Perl >= $1])
|
||||
has_wanted_perl="not found"
|
||||
if test -e "$PERL" && $PERL -e "require $1"; then
|
||||
has_wanted_perl=yes
|
||||
else
|
||||
DO_NOT_COMPILE="$DO_NOT_COMPILE $2"
|
||||
fi
|
||||
AC_MSG_RESULT($has_wanted_perl)
|
||||
])
|
||||
|
||||
dnl **********
|
||||
dnl check whether we need the qextmdi lib
|
||||
dnl (Shamlesly stolen from gideon souorces and
|
||||
dnl modified for quanta by fredi)
|
||||
dnl ..and borrowed again for a kdebindings test by rdale
|
||||
dnl **********
|
||||
|
||||
AC_DEFUN([KDE_CHECK_MDI],
|
||||
[
|
||||
AC_MSG_CHECKING(whether to use kmdi lib from kdelibs)
|
||||
AC_CACHE_VAL(ac_cv_mdi_setup,
|
||||
[
|
||||
AC_LANG_SAVE
|
||||
AC_LANG_CPLUSPLUS
|
||||
save_CXXFLAGS="$CXXFLAGS"
|
||||
CXXFLAGS="$KDE_INCLUDES $QT_INCLUDES $all_includes"
|
||||
|
||||
AC_TRY_COMPILE([
|
||||
#include <kdeversion.h>
|
||||
],
|
||||
[
|
||||
#if KDE_VERSION < ((3<<16) | (2<<8) | (0))
|
||||
KDE_choke me
|
||||
#endif
|
||||
],
|
||||
ac_cv_mdi_setup=yes,
|
||||
ac_cv_mdi_setup=no
|
||||
)
|
||||
CXXFLAGS="$save_CXXFLAGS"
|
||||
AC_LANG_RESTORE
|
||||
])
|
||||
|
||||
if test "$ac_cv_mdi_setup" = "yes"; then
|
||||
LIB_KMDI="-lkmdi"
|
||||
AC_MSG_RESULT(yes)
|
||||
else
|
||||
LIB_KMDI=''
|
||||
AC_MSG_RESULT(no)
|
||||
fi
|
||||
|
||||
AC_SUBST(LIB_KMDI)
|
||||
])
|
||||
|
||||
dnl Check if kmdi is present, if not don't bother..
|
||||
KDE_CHECK_MDI
|
||||
|
||||
|
||||
AC_DEFUN([KDE_CHECK_KNS],
|
||||
[
|
||||
AC_MSG_CHECKING(whether to use the knewstuff lib from kdelibs)
|
||||
AC_CACHE_VAL(ac_cv_kns_setup,
|
||||
[
|
||||
AC_LANG_SAVE
|
||||
AC_LANG_CPLUSPLUS
|
||||
save_CXXFLAGS="$CXXFLAGS"
|
||||
CXXFLAGS="$KDE_INCLUDES $QT_INCLUDES $all_includes"
|
||||
|
||||
AC_TRY_COMPILE([
|
||||
#include <kdeversion.h>
|
||||
],
|
||||
[
|
||||
#if KDE_VERSION < ((3<<16) | (3<<8) | (92))
|
||||
KDE_choke me
|
||||
#endif
|
||||
],
|
||||
ac_cv_kns_setup=yes,
|
||||
ac_cv_kns_setup=no
|
||||
)
|
||||
CXXFLAGS="$save_CXXFLAGS"
|
||||
AC_LANG_RESTORE
|
||||
])
|
||||
|
||||
if test "$ac_cv_kns_setup" = "yes"; then
|
||||
LIB_KNS="-lknewstuff"
|
||||
AC_MSG_RESULT(yes)
|
||||
else
|
||||
LIB_KNS=''
|
||||
AC_MSG_RESULT(no)
|
||||
fi
|
||||
|
||||
AC_SUBST(LIB_KNS)
|
||||
])
|
||||
|
||||
dnl Check if knewstuff is present, if not don't bother..
|
||||
KDE_CHECK_KNS
|
||||
|
||||
dnl remove when fixed
|
||||
DO_NOT_COMPILE="$DO_NOT_COMPILE dcopjava qtsharp"
|
@ -0,0 +1,20 @@
|
||||
AM_CFLAGS = $(GLIB_CFLAGS) $(GTK_CFLAGS)
|
||||
AM_CXXFLAGS = $(GLIB_CFLAGS) $(GTK_CFLAGS)
|
||||
|
||||
INCLUDES = -I$(top_srcdir)/ $(X_INCLUDES)
|
||||
|
||||
lib_LTLIBRARIES = libdcopc.la
|
||||
|
||||
libdcopc_la_SOURCES = dcopc.c marshal.c dcopobject.c
|
||||
libdcopc_la_LIBADD = -lSM -lICE $(GTK_LIBS) $(GLIB_LIBS)
|
||||
libdcopc_la_LDFLAGS = -version-info 1:0 $(X_LDFLAGS) -lICE -no-undefined
|
||||
|
||||
include_HEADERS = dcopc.h marshal.h dcopobject.h util.h
|
||||
includedir = $(prefix)/include/dcopc
|
||||
|
||||
noinst_HEADERS = global.h
|
||||
|
||||
check_PROGRAMS = glibtest
|
||||
|
||||
glibtest_SOURCES = glibtest.c
|
||||
glibtest_LDADD = libdcopc.la
|
@ -0,0 +1,5 @@
|
||||
dnl if test "$GTK_CONFIG" = "no"; then
|
||||
DO_NOT_COMPILE="$DO_NOT_COMPILE dcopc"
|
||||
dnl fi
|
||||
dnl
|
||||
dnl AC_CHECK_GETHOSTNAME
|
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,143 @@
|
||||
/*
|
||||
Copyright (c) 2000 Simon Hausmann <hausmann@kde.org>
|
||||
Copyright (c) 2000 Lars Knoll <knoll@kde.org>
|
||||
Copyright (c) 1999 Preston Brown <pbrown@kde.org>
|
||||
Copyright (c) 1999, 2000 Matthias Ettrich <ettrich@kde.org>
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
|
||||
AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef __dcopc_h__
|
||||
#define __dcopc_h__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <X11/ICE/ICElib.h>
|
||||
|
||||
#include <dcopc/marshal.h>
|
||||
#include <dcopc/util.h>
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
#define DCOP_TYPE_CLIENT (dcop_client_get_type())
|
||||
#define DCOP_CLIENT(obj) GTK_CHECK_CAST((obj), DCOP_TYPE_CLIENT, DcopClient)
|
||||
#define DCOP_CLIENT_CLASS(klass) GTK_CHECK_CLASS_CAST((klass), DCOP_TYPE_CLIENT, DcopClientClass)
|
||||
#define DCOP_IS_CLIENT(obj) GTK_CHECK_TYPE((obj), DCOP_TYPE_CLIENT)
|
||||
#define DCOP_IS_CLIENT_CLASS(klass) GTK_CHECK_CLASS_TYPE((klass), DCOP_TYPE_CLIENT)
|
||||
|
||||
typedef struct _DcopClient DcopClient;
|
||||
typedef struct _DcopClientClass DcopClientClass;
|
||||
|
||||
struct _DcopClient
|
||||
{
|
||||
GtkObject obj;
|
||||
void *priv;
|
||||
};
|
||||
|
||||
struct _DcopClientClass
|
||||
{
|
||||
GtkObjectClass parent_class;
|
||||
|
||||
gboolean (*process) ( DcopClient *client, const gchar *fun, dcop_data *data,
|
||||
gchar **reply_type, dcop_data **reply_data );
|
||||
};
|
||||
|
||||
typedef struct _DcopClientTransaction DcopClientTransaction;
|
||||
|
||||
extern GtkType dcop_client_get_type( void );
|
||||
|
||||
extern DcopClient *dcop_client_new( void );
|
||||
|
||||
void dcop_client_set_server_address( const gchar *addr );
|
||||
|
||||
gboolean dcop_client_attach( DcopClient *client );
|
||||
|
||||
gboolean dcop_client_detach( DcopClient *client );
|
||||
|
||||
gboolean dcop_client_is_attached( DcopClient *client );
|
||||
|
||||
const char *dcop_client_register_as( DcopClient *client, const gchar *app_id, gboolean add_pid /* = TRUE */ );
|
||||
|
||||
gboolean dcop_client_is_registered( DcopClient *client );
|
||||
|
||||
const gchar *dcop_client_app_id( DcopClient *client );
|
||||
|
||||
int dcop_client_socket( DcopClient *client );
|
||||
|
||||
gboolean dcop_client_send( DcopClient *client,
|
||||
const gchar *rem_app, const gchar *rem_obj, const gchar *rem_fun,
|
||||
dcop_data *data );
|
||||
|
||||
gboolean dcop_client_call( DcopClient *client,
|
||||
const gchar *rem_app, const gchar *rem_obj, const gchar *rem_fun,
|
||||
dcop_data *data,
|
||||
gchar **reply_type, dcop_data **reply_data );
|
||||
|
||||
DcopClientTransaction *dcop_client_begin_transaction( DcopClient *client );
|
||||
|
||||
void dcop_client_end_transaction( DcopClient *client, DcopClientTransaction *transaction, gchar *reply_type, dcop_data *reply_data );
|
||||
|
||||
gint32 dcop_client_transaction_id( DcopClient *client );
|
||||
|
||||
gboolean dcop_client_is_application_registered( DcopClient *client, const gchar *rem_app );
|
||||
|
||||
GList *dcop_client_registered_applications( DcopClient *client );
|
||||
|
||||
gboolean dcop_client_receive( DcopClient *client,
|
||||
const gchar *app, const gchar *obj, const gchar *fun,
|
||||
dcop_data *data,
|
||||
gchar **reply_type, dcop_data **reply_data );
|
||||
|
||||
gchar *dcop_client_normalize_function_signature( const gchar *fun );
|
||||
|
||||
const gchar *dcop_client_sender_id( DcopClient *client );
|
||||
|
||||
void dcop_client_set_default_object( DcopClient *client, const gchar *obj_id );
|
||||
|
||||
const gchar *dcop_client_default_object( DcopClient *client );
|
||||
|
||||
gboolean dcop_client_process ( DcopClient *client, const char *gfun, dcop_data *data,
|
||||
gchar **reply_type, dcop_data **reply_data );
|
||||
|
||||
void dcop_client_process_socket_data( DcopClient *client );
|
||||
|
||||
const gchar *dcop_client_error_message();
|
||||
|
||||
void dcop_client_emit_dcop_signal( DcopClient *client,
|
||||
const gchar *object, const gchar *signal, dcop_data *data );
|
||||
|
||||
gboolean dcop_client_connect_dcop_signal( DcopClient *client,
|
||||
const gchar *sender, const gchar *sender_obj,
|
||||
const gchar *signal,
|
||||
const gchar *receiver_obj, const gchar *slot,
|
||||
gboolean _volatile );
|
||||
|
||||
gboolean dcop_client_disconnect_dcop_signal( DcopClient *client,
|
||||
const gchar *sender, const gchar *sender_obj,
|
||||
const gchar *signal,
|
||||
const gchar *receiver_obj, const gchar *slot );
|
||||
|
||||
void dcop_client_set_daemon_mode( DcopClient *client, gboolean daemon );
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
@ -0,0 +1,301 @@
|
||||
/*
|
||||
Copyright (c) 2000 Simon Hausmann <hausmann@kde.org>
|
||||
Copyright (c) 2000 Lars Knoll <knoll@kde.org>
|
||||
Copyright (c) 1999 Preston Brown <pbrown@kde.org>
|
||||
Copyright (c) 1999, 2000 Matthias Ettrich <ettrich@kde.org>
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
|
||||
AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "dcopobject.h"
|
||||
#include "global.h"
|
||||
#include "dcopc.h"
|
||||
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#define OBJECT_CLASS(obj) DCOP_OBJECT_CLASS(GTK_OBJECT(obj)->klass)
|
||||
|
||||
typedef struct _DcopObjectPrivate DcopObjectPrivate;
|
||||
|
||||
struct _DcopObjectPrivate
|
||||
{
|
||||
gchar *id;
|
||||
};
|
||||
|
||||
/* initialization */
|
||||
static void dcop_object_class_init(DcopObjectClass *klass);
|
||||
|
||||
static void dcop_object_init(DcopObject *part);
|
||||
|
||||
/* GtkObject methods */
|
||||
static void dcop_object_destroy(GtkObject *object);
|
||||
|
||||
static GtkObjectClass *parent_class = 0;
|
||||
|
||||
GHashTable *object_dict = 0;
|
||||
|
||||
GtkType dcop_object_get_type(void)
|
||||
{
|
||||
static GtkType dcop_object_type = 0;
|
||||
if (!dcop_object_type)
|
||||
{
|
||||
static const GtkTypeInfo dcop_object_info =
|
||||
{
|
||||
(gchar *)"DcopObject",
|
||||
sizeof(DcopObject),
|
||||
sizeof(DcopObjectClass),
|
||||
(GtkClassInitFunc)dcop_object_class_init,
|
||||
(GtkObjectInitFunc)dcop_object_init,
|
||||
0,
|
||||
0,
|
||||
0
|
||||
};
|
||||
dcop_object_type = gtk_type_unique(GTK_TYPE_OBJECT, &dcop_object_info);
|
||||
}
|
||||
return dcop_object_type;
|
||||
}
|
||||
|
||||
gboolean dcop_object_real_process( DcopObject *obj, const gchar *fun, dcop_data *data,
|
||||
gchar **reply_type, dcop_data **reply_data );
|
||||
|
||||
gboolean dcop_object_real_process_dynamic( DcopObject *obj, const gchar *fun, dcop_data *data,
|
||||
gchar **reply_type, dcop_data **reply_data );
|
||||
|
||||
GList *dcop_object_real_functions( DcopObject *obj );
|
||||
|
||||
GList *dcop_object_real_interfaces( DcopObject *obj );
|
||||
|
||||
void dcop_object_class_init(DcopObjectClass *klass)
|
||||
{
|
||||
GtkObjectClass *object_class;
|
||||
object_class = (GtkObjectClass *)klass;
|
||||
|
||||
parent_class = (GtkObjectClass *)gtk_type_class(gtk_object_get_type());
|
||||
|
||||
object_class->destroy = dcop_object_destroy;
|
||||
|
||||
klass->process = dcop_object_real_process;
|
||||
klass->process_dynamic = dcop_object_real_process_dynamic;
|
||||
klass->functions = dcop_object_real_functions;
|
||||
klass->interfaces = dcop_object_real_interfaces;
|
||||
|
||||
g_message( "dcop_object_class_init(DcopObjectClass *klass)\n");
|
||||
}
|
||||
|
||||
void dcop_object_init(DcopObject *obj)
|
||||
{
|
||||
DcopObjectPrivate *d;
|
||||
/* eheh :-) (Simon)*/
|
||||
/* d = new DcopObjectPrivate();*/
|
||||
d = g_new( DcopObjectPrivate, 1 );
|
||||
d->id = 0;
|
||||
obj->data = d;
|
||||
|
||||
/* register a unique id*/
|
||||
{
|
||||
gchar n[1024];
|
||||
g_snprintf( n, sizeof( n ), "%p", obj );
|
||||
dcop_object_set_id( obj, n ); /* also registers the object at the object_dict*/
|
||||
}
|
||||
|
||||
g_message( "dcop_object_init(DcopObject *obj)\n");
|
||||
}
|
||||
|
||||
DcopObject *dcop_object_new (void)
|
||||
{
|
||||
DcopObject *obj = DCOP_OBJECT( gtk_type_new(dcop_object_get_type()) );
|
||||
|
||||
return obj;
|
||||
}
|
||||
|
||||
void dcop_object_destroy( GtkObject *obj )
|
||||
{
|
||||
DcopObject *o = DCOP_OBJECT(obj);
|
||||
DcopObjectPrivate *d = (DcopObjectPrivate *)o->data;
|
||||
|
||||
g_message( "dcop_object_destructor %s\n", DCOP_ID(o) );
|
||||
|
||||
g_assert( object_dict );
|
||||
g_assert( d->id );
|
||||
|
||||
g_hash_table_remove( object_dict, d->id );
|
||||
|
||||
if ( g_hash_table_size( object_dict ) == 0 )
|
||||
{
|
||||
g_hash_table_destroy( object_dict );
|
||||
object_dict = 0;
|
||||
}
|
||||
|
||||
g_free(d->id);
|
||||
/* Lars, you hack to much C++ :-))) (Simon)*/
|
||||
/* delete d;*/
|
||||
g_free( d );
|
||||
|
||||
parent_class->destroy(obj);
|
||||
}
|
||||
|
||||
void dcop_object_set_id( DcopObject *obj, const gchar *id )
|
||||
{
|
||||
DcopObjectPrivate *d = (DcopObjectPrivate *) obj->data;
|
||||
|
||||
if ( !object_dict )
|
||||
object_dict = g_hash_table_new( g_str_hash, g_str_equal );
|
||||
|
||||
if ( d->id )
|
||||
g_hash_table_remove( object_dict, d->id );
|
||||
|
||||
dcop_string_copy( d->id, id );
|
||||
|
||||
g_assert( d->id );
|
||||
|
||||
g_hash_table_insert( object_dict, d->id, obj );
|
||||
}
|
||||
|
||||
const gchar *dcop_object_get_id( DcopObject *obj)
|
||||
{
|
||||
return ((DcopObjectPrivate *) obj->data)->id;
|
||||
}
|
||||
|
||||
gboolean dcop_object_process( DcopObject *obj, const gchar *fun, dcop_data *data,
|
||||
gchar **reply_type, dcop_data **reply_data )
|
||||
{
|
||||
return OBJECT_CLASS(obj)->process( obj, fun, data, reply_type, reply_data );
|
||||
}
|
||||
|
||||
gboolean dcop_object_process_dynamic( DcopObject *obj, const gchar *fun, dcop_data *data,
|
||||
gchar **reply_type, dcop_data **reply_data )
|
||||
{
|
||||
return OBJECT_CLASS(obj)->process_dynamic( obj, fun, data, reply_type, reply_data );
|
||||
}
|
||||
|
||||
gboolean dcop_object_real_process( DcopObject *obj, const gchar *fun, dcop_data *data,
|
||||
gchar **reply_type, dcop_data **reply_data )
|
||||
{
|
||||
GList *strlist = 0;
|
||||
DcopObjectClass *klass = OBJECT_CLASS(obj);
|
||||
|
||||
if ( strcmp( fun, "interfaces()" ) == 0 )
|
||||
{
|
||||
*reply_type = g_strdup( "QCStringList" );
|
||||
*reply_data = dcop_data_ref( dcop_data_new() );
|
||||
strlist = klass->interfaces( obj );
|
||||
|
||||
dcop_marshal_stringlist( *reply_data, strlist );
|
||||
|
||||
dcop_list_free( strlist );
|
||||
return TRUE;
|
||||
}
|
||||
else if ( strcmp( fun, "functions()" ) == 0 )
|
||||
{
|
||||
*reply_type = strdup( "QCStringList" );
|
||||
*reply_data = dcop_data_ref( dcop_data_new() );
|
||||
strlist = klass->functions( obj );
|
||||
|
||||
dcop_marshal_stringlist( *reply_data, strlist );
|
||||
|
||||
dcop_list_free( strlist );
|
||||
return TRUE;
|
||||
}
|
||||
return klass->process_dynamic( obj, fun, data, reply_type, reply_data );
|
||||
}
|
||||
|
||||
gboolean dcop_object_real_process_dynamic( DcopObject *client, const gchar *fun, dcop_data *data,
|
||||
gchar **reply_type, dcop_data **reply_data )
|
||||
{
|
||||
/* empty default implementation*/
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
GList *dcop_object_functions( DcopObject *obj )
|
||||
{
|
||||
return OBJECT_CLASS(obj)->functions( obj );
|
||||
}
|
||||
|
||||
GList *dcop_object_interfaces( DcopObject *obj )
|
||||
{
|
||||
return OBJECT_CLASS(obj)->interfaces( obj );
|
||||
}
|
||||
|
||||
GList *dcop_object_real_functions( DcopObject *client )
|
||||
{
|
||||
GList *res = 0;
|
||||
res = g_list_append( res, g_strdup( "QCStringList interfaces()" ) );
|
||||
res = g_list_append( res, g_strdup( "QCStringList functions()" ) );
|
||||
return res;
|
||||
}
|
||||
|
||||
GList *dcop_object_real_interfaces( DcopObject *client )
|
||||
{
|
||||
GList *res = 0;
|
||||
res = g_list_append( res, g_strdup( "DCOPObject" ) );
|
||||
return res;
|
||||
}
|
||||
|
||||
DcopObject *dcop_object_lookup( const gchar *name )
|
||||
{
|
||||
DcopObject *res = 0;
|
||||
|
||||
if ( !object_dict || !name )
|
||||
return NULL;
|
||||
|
||||
return (DcopObject *)g_hash_table_lookup( object_dict, name );
|
||||
}
|
||||
|
||||
gchar *g_partial_id = 0;
|
||||
size_t g_id_len = 0;
|
||||
|
||||
static void dcop_object_match_internal( gpointer key, gpointer val, gpointer user_data )
|
||||
{
|
||||
GList **lst = (GList **)user_data;
|
||||
gchar *nam = (gchar *)key;
|
||||
DcopObjectPrivate *d = ((DcopObject *)val)->data;
|
||||
|
||||
if ( strncmp( d->id, g_partial_id, g_id_len ) == 0 )
|
||||
*lst = g_list_append( *lst, (DcopObject *)val );
|
||||
}
|
||||
|
||||
GList *dcop_object_match( const gchar *partial_id )
|
||||
{
|
||||
GList *res = 0;
|
||||
GList *it = 0;
|
||||
size_t id_len = strlen( partial_id );
|
||||
|
||||
if ( !object_dict )
|
||||
return res;
|
||||
|
||||
g_hash_table_foreach( object_dict, dcop_object_match_internal, &res );
|
||||
|
||||
/*
|
||||
if ( !object_list)
|
||||
return res;
|
||||
|
||||
it = g_list_first( object_list );
|
||||
|
||||
while ( it )
|
||||
{
|
||||
DcopObjectPrivate *d = (DcopObjectPrivate *)((DcopObject *)it->data)->data;
|
||||
|
||||
if ( strncmp( d->id, partial_id, id_len ) == 0 )
|
||||
res = g_list_append( res, (DcopObject *)it->data );
|
||||
|
||||
it = g_list_next( it );
|
||||
}
|
||||
*/
|
||||
return res;
|
||||
}
|
@ -0,0 +1,93 @@
|
||||
/*
|
||||
Copyright (c) 2000 Simon Hausmann <hausmann@kde.org>
|
||||
Copyright (c) 2000 Lars Knoll <knoll@kde.org>
|
||||
Copyright (c) 1999 Preston Brown <pbrown@kde.org>
|
||||
Copyright (c) 1999, 2000 Matthias Ettrich <ettrich@kde.org>
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
|
||||
AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef __dcopc_dcopobject_h__
|
||||
#define __dcopc_dcopobject_h__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <X11/ICE/ICElib.h>
|
||||
|
||||
#include <dcopc/marshal.h>
|
||||
#include <dcopc/util.h>
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
#define DCOP_TYPE_OBJECT (dcop_object_get_type())
|
||||
#define DCOP_OBJECT(obj) GTK_CHECK_CAST((obj), DCOP_TYPE_OBJECT, DcopObject)
|
||||
#define DCOP_OBJECT_CLASS(klass) GTK_CHECK_CLASS_CAST((klass), DCOP_TYPE_OBJECT, DcopObjectClass)
|
||||
#define DCOP_IS_OBJECT(obj) GTK_CHECK_TYPE((obj), DCOP_TYPE_OBJECT)
|
||||
#define DCOP_IS_OBJECT_CLASS(klass) GTK_CHECK_CLASS_TYPE((klass), DCOP_TYPE_OBJECT)
|
||||
#define DCOP_ID(obj) (dcop_object_get_id(obj))
|
||||
|
||||
typedef struct _DcopObject DcopObject;
|
||||
typedef struct _DcopObjectClass DcopObjectClass;
|
||||
|
||||
struct _DcopObject
|
||||
{
|
||||
GtkObject obj;
|
||||
void *data;
|
||||
};
|
||||
|
||||
struct _DcopObjectClass
|
||||
{
|
||||
GtkObjectClass parent_class;
|
||||
|
||||
gboolean (*process) ( DcopObject *obj, const gchar *fun, dcop_data *data,
|
||||
gchar **reply_type, dcop_data **reply_data );
|
||||
gboolean (*process_dynamic) ( DcopObject *obj, const gchar *fun, dcop_data *data,
|
||||
gchar **reply_type, dcop_data **reply_data );
|
||||
|
||||
GList *(*functions) ( DcopObject *obj );
|
||||
GList *(*interfaces) ( DcopObject *obj );
|
||||
};
|
||||
|
||||
GtkType dcop_object_get_type(void);
|
||||
|
||||
DcopObject *dcop_object_new( void );
|
||||
|
||||
void dcop_object_set_id( DcopObject *obj, const gchar *id );
|
||||
const gchar *dcop_object_get_id( DcopObject *obj);
|
||||
|
||||
gboolean dcop_object_process( DcopObject *obj, const gchar *fun, dcop_data *data,
|
||||
gchar **reply_type, dcop_data **reply_data );
|
||||
|
||||
gboolean dcop_object_process_dynamic( DcopObject *obj, const gchar *fun, dcop_data *data,
|
||||
gchar **reply_type, dcop_data **reply_data );
|
||||
|
||||
GList *dcop_object_functions( DcopObject *obj );
|
||||
|
||||
GList *dcop_object_interfaces( DcopObject *obj );
|
||||
|
||||
DcopObject *dcop_object_lookup( const gchar *name );
|
||||
|
||||
GList *dcop_object_match( const gchar *partial_id );
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
@ -0,0 +1,196 @@
|
||||
# Configure paths for GLIB
|
||||
# Owen Taylor 97-11-3
|
||||
|
||||
dnl AM_PATH_GLIB([MINIMUM-VERSION, [ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND [, MODULES]]]])
|
||||
dnl Test for GLIB, and define GLIB_CFLAGS and GLIB_LIBS, if "gmodule" or
|
||||
dnl gthread is specified in MODULES, pass to glib-config
|
||||
dnl
|
||||
AC_DEFUN(AM_PATH_GLIB,
|
||||
[dnl
|
||||
dnl Get the cflags and libraries from the glib-config script
|
||||
dnl
|
||||
AC_ARG_WITH(glib-prefix,[ --with-glib-prefix=PFX Prefix where GLIB is installed (optional)],
|
||||
glib_config_prefix="$withval", glib_config_prefix="")
|
||||
AC_ARG_WITH(glib-exec-prefix,[ --with-glib-exec-prefix=PFX Exec prefix where GLIB is installed (optional)],
|
||||
glib_config_exec_prefix="$withval", glib_config_exec_prefix="")
|
||||
AC_ARG_ENABLE(glibtest, [ --disable-glibtest Do not try to compile and run a test GLIB program],
|
||||
, enable_glibtest=yes)
|
||||
|
||||
if test x$glib_config_exec_prefix != x ; then
|
||||
glib_config_args="$glib_config_args --exec-prefix=$glib_config_exec_prefix"
|
||||
if test x${GLIB_CONFIG+set} != xset ; then
|
||||
GLIB_CONFIG=$glib_config_exec_prefix/bin/glib-config
|
||||
fi
|
||||
fi
|
||||
if test x$glib_config_prefix != x ; then
|
||||
glib_config_args="$glib_config_args --prefix=$glib_config_prefix"
|
||||
if test x${GLIB_CONFIG+set} != xset ; then
|
||||
GLIB_CONFIG=$glib_config_prefix/bin/glib-config
|
||||
fi
|
||||
fi
|
||||
|
||||
for module in . $4
|
||||
do
|
||||
case "$module" in
|
||||
gmodule)
|
||||
glib_config_args="$glib_config_args gmodule"
|
||||
;;
|
||||
gthread)
|
||||
glib_config_args="$glib_config_args gthread"
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
AC_PATH_PROG(GLIB_CONFIG, glib-config, no)
|
||||
min_glib_version=ifelse([$1], ,0.99.7,$1)
|
||||
AC_MSG_CHECKING(for GLIB - version >= $min_glib_version)
|
||||
no_glib=""
|
||||
if test "$GLIB_CONFIG" = "no" ; then
|
||||
no_glib=yes
|
||||
else
|
||||
GLIB_CFLAGS=`$GLIB_CONFIG $glib_config_args --cflags`
|
||||
GLIB_LIBS=`$GLIB_CONFIG $glib_config_args --libs`
|
||||
glib_config_major_version=`$GLIB_CONFIG $glib_config_args --version | \
|
||||
sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\1/'`
|
||||
glib_config_minor_version=`$GLIB_CONFIG $glib_config_args --version | \
|
||||
sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\2/'`
|
||||
glib_config_micro_version=`$GLIB_CONFIG $glib_config_args --version | \
|
||||
sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\3/'`
|
||||
if test "x$enable_glibtest" = "xyes" ; then
|
||||
ac_save_CFLAGS="$CFLAGS"
|
||||
ac_save_LIBS="$LIBS"
|
||||
CFLAGS="$CFLAGS $GLIB_CFLAGS"
|
||||
LIBS="$GLIB_LIBS $LIBS"
|
||||
dnl
|
||||
dnl Now check if the installed GLIB is sufficiently new. (Also sanity
|
||||
dnl checks the results of glib-config to some extent
|
||||
dnl
|
||||
rm -f conf.glibtest
|
||||
AC_TRY_RUN([
|
||||
#include <glib.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
int
|
||||
main ()
|
||||
{
|
||||
int major, minor, micro;
|
||||
char *tmp_version;
|
||||
|
||||
system ("touch conf.glibtest");
|
||||
|
||||
/* HP/UX 9 (%@#!) writes to sscanf strings */
|
||||
tmp_version = g_strdup("$min_glib_version");
|
||||
if (sscanf(tmp_version, "%d.%d.%d", &major, &minor, µ) != 3) {
|
||||
printf("%s, bad version string\n", "$min_glib_version");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if ((glib_major_version != $glib_config_major_version) ||
|
||||
(glib_minor_version != $glib_config_minor_version) ||
|
||||
(glib_micro_version != $glib_config_micro_version))
|
||||
{
|
||||
printf("\n*** 'glib-config --version' returned %d.%d.%d, but GLIB (%d.%d.%d)\n",
|
||||
$glib_config_major_version, $glib_config_minor_version, $glib_config_micro_version,
|
||||
glib_major_version, glib_minor_version, glib_micro_version);
|
||||
printf ("*** was found! If glib-config was correct, then it is best\n");
|
||||
printf ("*** to remove the old version of GLIB. You may also be able to fix the error\n");
|
||||
printf("*** by modifying your LD_LIBRARY_PATH enviroment variable, or by editing\n");
|
||||
printf("*** /etc/ld.so.conf. Make sure you have run ldconfig if that is\n");
|
||||
printf("*** required on your system.\n");
|
||||
printf("*** If glib-config was wrong, set the environment variable GLIB_CONFIG\n");
|
||||
printf("*** to point to the correct copy of glib-config, and remove the file config.cache\n");
|
||||
printf("*** before re-running configure\n");
|
||||
}
|
||||
else if ((glib_major_version != GLIB_MAJOR_VERSION) ||
|
||||
(glib_minor_version != GLIB_MINOR_VERSION) ||
|
||||
(glib_micro_version != GLIB_MICRO_VERSION))
|
||||
{
|
||||
printf("*** GLIB header files (version %d.%d.%d) do not match\n",
|
||||
GLIB_MAJOR_VERSION, GLIB_MINOR_VERSION, GLIB_MICRO_VERSION);
|
||||
printf("*** library (version %d.%d.%d)\n",
|
||||
glib_major_version, glib_minor_version, glib_micro_version);
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((glib_major_version > major) ||
|
||||
((glib_major_version == major) && (glib_minor_version > minor)) ||
|
||||
((glib_major_version == major) && (glib_minor_version == minor) && (glib_micro_version >= micro)))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("\n*** An old version of GLIB (%d.%d.%d) was found.\n",
|
||||
glib_major_version, glib_minor_version, glib_micro_version);
|
||||
printf("*** You need a version of GLIB newer than %d.%d.%d. The latest version of\n",
|
||||
major, minor, micro);
|
||||
printf("*** GLIB is always available from ftp://ftp.gtk.org.\n");
|
||||
printf("***\n");
|
||||
printf("*** If you have already installed a sufficiently new version, this error\n");
|
||||
printf("*** probably means that the wrong copy of the glib-config shell script is\n");
|
||||
printf("*** being found. The easiest way to fix this is to remove the old version\n");
|
||||
printf("*** of GLIB, but you can also set the GLIB_CONFIG environment to point to the\n");
|
||||
printf("*** correct copy of glib-config. (In this case, you will have to\n");
|
||||
printf("*** modify your LD_LIBRARY_PATH enviroment variable, or edit /etc/ld.so.conf\n");
|
||||
printf("*** so that the correct libraries are found at run-time))\n");
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
],, no_glib=yes,[echo $ac_n "cross compiling; assumed OK... $ac_c"])
|
||||
CFLAGS="$ac_save_CFLAGS"
|
||||
LIBS="$ac_save_LIBS"
|
||||
fi
|
||||
fi
|
||||
if test "x$no_glib" = x ; then
|
||||
AC_MSG_RESULT(yes)
|
||||
ifelse([$2], , :, [$2])
|
||||
else
|
||||
AC_MSG_RESULT(no)
|
||||
if test "$GLIB_CONFIG" = "no" ; then
|
||||
echo "*** The glib-config script installed by GLIB could not be found"
|
||||
echo "*** If GLIB was installed in PREFIX, make sure PREFIX/bin is in"
|
||||
echo "*** your path, or set the GLIB_CONFIG environment variable to the"
|
||||
echo "*** full path to glib-config."
|
||||
else
|
||||
if test -f conf.glibtest ; then
|
||||
:
|
||||
else
|
||||
echo "*** Could not run GLIB test program, checking why..."
|
||||
CFLAGS="$CFLAGS $GLIB_CFLAGS"
|
||||
LIBS="$LIBS $GLIB_LIBS"
|
||||
AC_TRY_LINK([
|
||||
#include <glib.h>
|
||||
#include <stdio.h>
|
||||
], [ return ((glib_major_version) || (glib_minor_version) || (glib_micro_version)); ],
|
||||
[ echo "*** The test program compiled, but did not run. This usually means"
|
||||
echo "*** that the run-time linker is not finding GLIB or finding the wrong"
|
||||
echo "*** version of GLIB. If it is not finding GLIB, you'll need to set your"
|
||||
echo "*** LD_LIBRARY_PATH environment variable, or edit /etc/ld.so.conf to point"
|
||||
echo "*** to the installed location Also, make sure you have run ldconfig if that"
|
||||
echo "*** is required on your system"
|
||||
echo "***"
|
||||
echo "*** If you have an old version installed, it is best to remove it, although"
|
||||
echo "*** you may also be able to get things to work by modifying LD_LIBRARY_PATH"
|
||||
echo "***"
|
||||
echo "*** If you have a RedHat 5.0 system, you should remove the GTK package that"
|
||||
echo "*** came with the system with the command"
|
||||
echo "***"
|
||||
echo "*** rpm --erase --nodeps gtk gtk-devel" ],
|
||||
[ echo "*** The test program failed to compile or link. See the file config.log for the"
|
||||
echo "*** exact error that occured. This usually means GLIB was incorrectly installed"
|
||||
echo "*** or that you have moved GLIB since it was installed. In the latter case, you"
|
||||
echo "*** may want to edit the glib-config script: $GLIB_CONFIG" ])
|
||||
CFLAGS="$ac_save_CFLAGS"
|
||||
LIBS="$ac_save_LIBS"
|
||||
fi
|
||||
fi
|
||||
GLIB_CFLAGS=""
|
||||
GLIB_LIBS=""
|
||||
ifelse([$3], , :, [$3])
|
||||
fi
|
||||
AC_SUBST(GLIB_CFLAGS)
|
||||
AC_SUBST(GLIB_LIBS)
|
||||
rm -f conf.glibtest
|
||||
])
|
@ -0,0 +1,133 @@
|
||||
/*
|
||||
Copyright (c) 2000 Simon Hausmann <hausmann@kde.org>
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
|
||||
AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <dcopc/dcopc.h>
|
||||
#include <dcopc/dcopobject.h>
|
||||
#include <stdio.h>
|
||||
#include <glib.h>
|
||||
|
||||
#define C( call ) \
|
||||
if ( !call ) \
|
||||
{ \
|
||||
fprintf( stderr, "dcop error: %s\n", dcop_client_error_message() ); \
|
||||
return 1; \
|
||||
}
|
||||
|
||||
gboolean dcop_socket_notify( GIOChannel *chan, GIOCondition condition, gpointer data )
|
||||
{
|
||||
DcopClient *client = (DcopClient *)data;
|
||||
fprintf( stderr, "dcop_socket_notify\n" );
|
||||
dcop_client_process_socket_data( client );
|
||||
}
|
||||
|
||||
gboolean (*old_process_func) ( DcopObject *obj, const gchar *fun, dcop_data *data,
|
||||
gchar **reply_type, dcop_data **reply_data );
|
||||
|
||||
gboolean my_obj_process( DcopObject *obj, const gchar *fun, dcop_data *data,
|
||||
gchar **reply_type, dcop_data **reply_data )
|
||||
{
|
||||
if ( strcmp( fun, "doExit()" ) == 0 )
|
||||
{
|
||||
gtk_main_quit();
|
||||
return TRUE;
|
||||
}
|
||||
if ( strcmp( fun, "mySlot()" ) == 0 )
|
||||
{
|
||||
g_message( "mySlot called!" );
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return old_process_func( obj, fun, data, reply_type, reply_data );
|
||||
}
|
||||
|
||||
GList *(*old_functions_func)( DcopObject *obj ) = 0;
|
||||
|
||||
GList *my_obj_functions( DcopObject *obj )
|
||||
{
|
||||
GList *res = old_functions_func( obj );
|
||||
res = g_list_append( res, g_strdup( "doExit()" ) );
|
||||
res = g_list_append( res, g_strdup( "mySlot()" ) );
|
||||
return res;
|
||||
}
|
||||
|
||||
GList *(*old_interfaces_func)( DcopObject *obj ) = 0;
|
||||
|
||||
GList *my_obj_interfaces( DcopObject *obj )
|
||||
{
|
||||
GList *res = old_interfaces_func( obj );
|
||||
res = g_list_append( res, g_strdup( "MyObj" ) );
|
||||
return res;
|
||||
}
|
||||
|
||||
int main( int argc, char **argv )
|
||||
{
|
||||
DcopClient *c;
|
||||
dcop_data *d;
|
||||
dcop_data *reply;
|
||||
char *reply_type;
|
||||
GIOChannel *chan;
|
||||
DcopObject *obj;
|
||||
|
||||
gtk_init( &argc, &argv );
|
||||
|
||||
c = dcop_client_new();
|
||||
|
||||
C( dcop_client_register_as( c, "dcoptest", False ) );
|
||||
|
||||
chan = g_io_channel_unix_new( dcop_client_socket( c ) );
|
||||
g_io_channel_ref( chan );
|
||||
|
||||
g_io_add_watch( chan, G_IO_IN, dcop_socket_notify, c );
|
||||
|
||||
obj = dcop_object_new();
|
||||
dcop_object_set_id( obj, "myServer" );
|
||||
|
||||
old_process_func = DCOP_OBJECT_CLASS( GTK_OBJECT( obj )->klass )->process;
|
||||
old_functions_func = DCOP_OBJECT_CLASS( GTK_OBJECT( obj )->klass )->functions;
|
||||
old_interfaces_func = DCOP_OBJECT_CLASS( GTK_OBJECT( obj )->klass )->interfaces;
|
||||
|
||||
DCOP_OBJECT_CLASS( GTK_OBJECT( obj )->klass )->process = my_obj_process;
|
||||
DCOP_OBJECT_CLASS( GTK_OBJECT( obj )->klass )->functions = my_obj_functions;
|
||||
DCOP_OBJECT_CLASS( GTK_OBJECT( obj )->klass )->interfaces = my_obj_interfaces;
|
||||
|
||||
if ( dcop_client_connect_dcop_signal( c, dcop_client_app_id( c ), "myServer",
|
||||
"mySignal()",
|
||||
"myServer", "mySlot()", FALSE ) == FALSE )
|
||||
g_message( "error connecting dcop signal :-(" );
|
||||
|
||||
d = dcop_data_ref( dcop_data_new() );
|
||||
|
||||
dcop_client_emit_dcop_signal( c, "myServer", "mySignal()", d );
|
||||
|
||||
dcop_data_deref( d );
|
||||
|
||||
dcop_client_set_daemon_mode( c, TRUE );
|
||||
|
||||
gtk_main();
|
||||
|
||||
g_io_channel_unref( chan );
|
||||
|
||||
C( dcop_client_detach( c ) );
|
||||
|
||||
gtk_object_unref( GTK_OBJECT( c ) );
|
||||
|
||||
return 0;
|
||||
}
|
@ -0,0 +1,75 @@
|
||||
/*
|
||||
Copyright (c) 1999 Preston Brown <pbrown@kde.org>
|
||||
Copyright (c) 1999, 2000 Matthias Ettrich <ettrich@kde.org>
|
||||
Copyright (c) 2000 Simon Hausmann <hausmann@kde.org>
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
|
||||
AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
#ifndef __global_h__
|
||||
#define __global_h__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "util.h"
|
||||
|
||||
/* sometimes __STDC__ is defined, but to 0. The hateful X headers
|
||||
ask for '#if __STDC__', so they become confused. */
|
||||
#if defined(__STDC__)
|
||||
#if !__STDC__
|
||||
#undef __STDC__
|
||||
#define __STDC__ 1
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#include <X11/Xlib.h>
|
||||
#include <X11/Xmd.h>
|
||||
#include <X11/ICE/ICElib.h>
|
||||
|
||||
#include <X11/ICE/ICEutil.h>
|
||||
#include <X11/ICE/ICEmsg.h>
|
||||
#include <X11/ICE/ICEproto.h>
|
||||
|
||||
|
||||
#define DCOPVendorString "KDE"
|
||||
#define DCOPReleaseString "2.0"
|
||||
#define DCOPVersionMajor 2
|
||||
#define DCOPVersionMinor 0
|
||||
|
||||
#define DCOPSend 1
|
||||
#define DCOPCall 2
|
||||
#define DCOPReply 3
|
||||
#define DCOPReplyFailed 4
|
||||
#define DCOPReplyWait 5
|
||||
#define DCOPReplyDelayed 6
|
||||
#define DCOPFind 7
|
||||
|
||||
struct DCOPMsg {
|
||||
CARD8 majorOpcode;
|
||||
CARD8 minorOpcode;
|
||||
CARD8 data[2];
|
||||
CARD32 length B32;
|
||||
CARD32 key;
|
||||
};
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
@ -0,0 +1,197 @@
|
||||
# Configure paths for GTK+
|
||||
# Owen Taylor 97-11-3
|
||||
|
||||
dnl AM_PATH_GTK([MINIMUM-VERSION, [ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND [, MODULES]]]])
|
||||
dnl Test for GTK, and define GTK_CFLAGS and GTK_LIBS
|
||||
dnl
|
||||
AC_DEFUN(AM_PATH_GTK,
|
||||
[dnl
|
||||
dnl Get the cflags and libraries from the gtk-config script
|
||||
dnl
|
||||
AC_ARG_WITH(gtk-prefix,[ --with-gtk-prefix=PFX Prefix where GTK is installed (optional)],
|
||||
gtk_config_prefix="$withval", gtk_config_prefix="")
|
||||
AC_ARG_WITH(gtk-exec-prefix,[ --with-gtk-exec-prefix=PFX Exec prefix where GTK is installed (optional)],
|
||||
gtk_config_exec_prefix="$withval", gtk_config_exec_prefix="")
|
||||
AC_ARG_ENABLE(gtktest, [ --disable-gtktest Do not try to compile and run a test GTK program],
|
||||
, enable_gtktest=yes)
|
||||
|
||||
for module in . $4
|
||||
do
|
||||
case "$module" in
|
||||
gthread)
|
||||
gtk_config_args="$gtk_config_args gthread"
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
if test x$gtk_config_exec_prefix != x ; then
|
||||
gtk_config_args="$gtk_config_args --exec-prefix=$gtk_config_exec_prefix"
|
||||
if test x${GTK_CONFIG+set} != xset ; then
|
||||
GTK_CONFIG=$gtk_config_exec_prefix/bin/gtk-config
|
||||
fi
|
||||
fi
|
||||
if test x$gtk_config_prefix != x ; then
|
||||
gtk_config_args="$gtk_config_args --prefix=$gtk_config_prefix"
|
||||
if test x${GTK_CONFIG+set} != xset ; then
|
||||
GTK_CONFIG=$gtk_config_prefix/bin/gtk-config
|
||||
fi
|
||||
fi
|
||||
|
||||
AC_PATH_PROG(GTK_CONFIG, gtk-config, no)
|
||||
min_gtk_version=ifelse([$1], ,0.99.7,$1)
|
||||
AC_MSG_CHECKING(for GTK - version >= $min_gtk_version)
|
||||
no_gtk=""
|
||||
if test "$GTK_CONFIG" = "no" ; then
|
||||
no_gtk=yes
|
||||
else
|
||||
GTK_CFLAGS=`$GTK_CONFIG $gtk_config_args --cflags`
|
||||
GTK_LIBS=`$GTK_CONFIG $gtk_config_args --libs`
|
||||
gtk_config_major_version=`$GTK_CONFIG $gtk_config_args --version | \
|
||||
sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\1/'`
|
||||
gtk_config_minor_version=`$GTK_CONFIG $gtk_config_args --version | \
|
||||
sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\2/'`
|
||||
gtk_config_micro_version=`$GTK_CONFIG $gtk_config_args --version | \
|
||||
sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\3/'`
|
||||
if test "x$enable_gtktest" = "xyes" ; then
|
||||
ac_save_CFLAGS="$CFLAGS"
|
||||
ac_save_LIBS="$LIBS"
|
||||
CFLAGS="$CFLAGS $GTK_CFLAGS"
|
||||
LIBS="$GTK_LIBS $LIBS"
|
||||
AC_LANG_SAVE
|
||||
AC_LANG_C
|
||||
dnl
|
||||
dnl Now check if the installed GTK is sufficiently new. (Also sanity
|
||||
dnl checks the results of gtk-config to some extent
|
||||
dnl
|
||||
rm -f conf.gtktest
|
||||
AC_TRY_RUN([
|
||||
#include <gtk/gtk.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
int
|
||||
main ()
|
||||
{
|
||||
int major, minor, micro;
|
||||
char *tmp_version;
|
||||
|
||||
system ("touch conf.gtktest");
|
||||
|
||||
/* HP/UX 9 (%@#!) writes to sscanf strings */
|
||||
tmp_version = g_strdup("$min_gtk_version");
|
||||
if (sscanf(tmp_version, "%d.%d.%d", &major, &minor, µ) != 3) {
|
||||
printf("%s, bad version string\n", "$min_gtk_version");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if ((gtk_major_version != $gtk_config_major_version) ||
|
||||
(gtk_minor_version != $gtk_config_minor_version) ||
|
||||
(gtk_micro_version != $gtk_config_micro_version))
|
||||
{
|
||||
printf("\n*** 'gtk-config --version' returned %d.%d.%d, but GTK+ (%d.%d.%d)\n",
|
||||
$gtk_config_major_version, $gtk_config_minor_version, $gtk_config_micro_version,
|
||||
gtk_major_version, gtk_minor_version, gtk_micro_version);
|
||||
printf ("*** was found! If gtk-config was correct, then it is best\n");
|
||||
printf ("*** to remove the old version of GTK+. You may also be able to fix the error\n");
|
||||
printf("*** by modifying your LD_LIBRARY_PATH enviroment variable, or by editing\n");
|
||||
printf("*** /etc/ld.so.conf. Make sure you have run ldconfig if that is\n");
|
||||
printf("*** required on your system.\n");
|
||||
printf("*** If gtk-config was wrong, set the environment variable GTK_CONFIG\n");
|
||||
printf("*** to point to the correct copy of gtk-config, and remove the file config.cache\n");
|
||||
printf("*** before re-running configure\n");
|
||||
}
|
||||
#if defined (GTK_MAJOR_VERSION) && defined (GTK_MINOR_VERSION) && defined (GTK_MICRO_VERSION)
|
||||
else if ((gtk_major_version != GTK_MAJOR_VERSION) ||
|
||||
(gtk_minor_version != GTK_MINOR_VERSION) ||
|
||||
(gtk_micro_version != GTK_MICRO_VERSION))
|
||||
{
|
||||
printf("*** GTK+ header files (version %d.%d.%d) do not match\n",
|
||||
GTK_MAJOR_VERSION, GTK_MINOR_VERSION, GTK_MICRO_VERSION);
|
||||
printf("*** library (version %d.%d.%d)\n",
|
||||
gtk_major_version, gtk_minor_version, gtk_micro_version);
|
||||
}
|
||||
#endif /* defined (GTK_MAJOR_VERSION) ... */
|
||||
else
|
||||
{
|
||||
if ((gtk_major_version > major) ||
|
||||
((gtk_major_version == major) && (gtk_minor_version > minor)) ||
|
||||
((gtk_major_version == major) && (gtk_minor_version == minor) && (gtk_micro_version >= micro)))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("\n*** An old version of GTK+ (%d.%d.%d) was found.\n",
|
||||
gtk_major_version, gtk_minor_version, gtk_micro_version);
|
||||
printf("*** You need a version of GTK+ newer than %d.%d.%d. The latest version of\n",
|
||||
major, minor, micro);
|
||||
printf("*** GTK+ is always available from ftp://ftp.gtk.org.\n");
|
||||
printf("***\n");
|
||||
printf("*** If you have already installed a sufficiently new version, this error\n");
|
||||
printf("*** probably means that the wrong copy of the gtk-config shell script is\n");
|
||||
printf("*** being found. The easiest way to fix this is to remove the old version\n");
|
||||
printf("*** of GTK+, but you can also set the GTK_CONFIG environment to point to the\n");
|
||||
printf("*** correct copy of gtk-config. (In this case, you will have to\n");
|
||||
printf("*** modify your LD_LIBRARY_PATH enviroment variable, or edit /etc/ld.so.conf\n");
|
||||
printf("*** so that the correct libraries are found at run-time))\n");
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
],, no_gtk=yes,[echo $ac_n "cross compiling; assumed OK... $ac_c"])
|
||||
CFLAGS="$ac_save_CFLAGS"
|
||||
LIBS="$ac_save_LIBS"
|
||||
AC_LANG_RESTORE
|
||||
fi
|
||||
fi
|
||||
if test "x$no_gtk" = x ; then
|
||||
AC_MSG_RESULT(yes)
|
||||
ifelse([$2], , :, [$2])
|
||||
else
|
||||
AC_MSG_RESULT(no)
|
||||
if test "$GTK_CONFIG" = "no" ; then
|
||||
echo "*** The gtk-config script installed by GTK could not be found"
|
||||
echo "*** If GTK was installed in PREFIX, make sure PREFIX/bin is in"
|
||||
echo "*** your path, or set the GTK_CONFIG environment variable to the"
|
||||
echo "*** full path to gtk-config."
|
||||
else
|
||||
if test -f conf.gtktest ; then
|
||||
:
|
||||
else
|
||||
echo "*** Could not run GTK test program, checking why..."
|
||||
CFLAGS="$CFLAGS $GTK_CFLAGS"
|
||||
LIBS="$LIBS $GTK_LIBS"
|
||||
AC_TRY_LINK([
|
||||
#include <gtk/gtk.h>
|
||||
#include <stdio.h>
|
||||
], [ return ((gtk_major_version) || (gtk_minor_version) || (gtk_micro_version)); ],
|
||||
[ echo "*** The test program compiled, but did not run. This usually means"
|
||||
echo "*** that the run-time linker is not finding GTK or finding the wrong"
|
||||
echo "*** version of GTK. If it is not finding GTK, you'll need to set your"
|
||||
echo "*** LD_LIBRARY_PATH environment variable, or edit /etc/ld.so.conf to point"
|
||||
echo "*** to the installed location Also, make sure you have run ldconfig if that"
|
||||
echo "*** is required on your system"
|
||||
echo "***"
|
||||
echo "*** If you have an old version installed, it is best to remove it, although"
|
||||
echo "*** you may also be able to get things to work by modifying LD_LIBRARY_PATH"
|
||||
echo "***"
|
||||
echo "*** If you have a RedHat 5.0 system, you should remove the GTK package that"
|
||||
echo "*** came with the system with the command"
|
||||
echo "***"
|
||||
echo "*** rpm --erase --nodeps gtk gtk-devel" ],
|
||||
[ echo "*** The test program failed to compile or link. See the file config.log for the"
|
||||
echo "*** exact error that occured. This usually means GTK was incorrectly installed"
|
||||
echo "*** or that you have moved GTK since it was installed. In the latter case, you"
|
||||
echo "*** may want to edit the gtk-config script: $GTK_CONFIG" ])
|
||||
CFLAGS="$ac_save_CFLAGS"
|
||||
LIBS="$ac_save_LIBS"
|
||||
fi
|
||||
fi
|
||||
GTK_CFLAGS=""
|
||||
GTK_LIBS=""
|
||||
ifelse([$3], , :, [$3])
|
||||
fi
|
||||
AC_SUBST(GTK_CFLAGS)
|
||||
AC_SUBST(GTK_LIBS)
|
||||
rm -f conf.gtktest
|
||||
])
|
@ -0,0 +1,420 @@
|
||||
/*
|
||||
Copyright (c) 2000 Simon Hausmann <hausmann@kde.org>
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
|
||||
AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "marshal.h"
|
||||
|
||||
#include <glib.h>
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
dcop_data *dcop_data_new()
|
||||
{
|
||||
dcop_data *res = g_new( dcop_data, 1 );
|
||||
|
||||
res->ptr = 0;
|
||||
res->size = 0;
|
||||
res->cur = 0;
|
||||
res->ref = 0;
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
void dcop_data_destroy( dcop_data *data )
|
||||
{
|
||||
g_assert( data->ref == 0 );
|
||||
|
||||
g_free( data->ptr );
|
||||
|
||||
g_free( data );
|
||||
}
|
||||
|
||||
dcop_data *dcop_data_copy( dcop_data *data )
|
||||
{
|
||||
dcop_data *res = dcop_data_new();
|
||||
res->ptr = (char *)g_malloc( data->size );
|
||||
res->size = data->size;
|
||||
dcop_data_reset( res );
|
||||
memcpy( res->ptr, data->ptr, data->size );
|
||||
return res;
|
||||
}
|
||||
|
||||
static gboolean dcop_data_check_size( dcop_data *data, unsigned int size )
|
||||
{
|
||||
if ( data->size - ( data->cur - data->ptr ) < size )
|
||||
return FALSE;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
gboolean dcop_marshal_raw( dcop_data *data, const void *ptr, unsigned int size )
|
||||
{
|
||||
unsigned int relptr = data->cur - data->ptr;
|
||||
|
||||
data->ptr = (char *)g_realloc( data->ptr, data->size + size );
|
||||
|
||||
if ( data->ptr == 0 )
|
||||
return FALSE;
|
||||
|
||||
data->cur = data->ptr + relptr;
|
||||
|
||||
memcpy( data->cur, ptr, size );
|
||||
|
||||
data->cur += size;
|
||||
data->size += size;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
gboolean dcop_marshal_uint32( dcop_data *data, unsigned int val )
|
||||
{
|
||||
unsigned char buf[4];
|
||||
|
||||
g_assert( sizeof( unsigned int ) == 4 );
|
||||
|
||||
buf[0] = val;
|
||||
buf[1] = val >> 8;
|
||||
buf[2] = val >> 16;
|
||||
buf[3] = val >> 24;
|
||||
|
||||
return dcop_marshal_raw( data, buf, 4 );
|
||||
}
|
||||
|
||||
gboolean dcop_demarshal_uint32( dcop_data *data, unsigned int *val )
|
||||
{
|
||||
g_assert( sizeof( unsigned int ) == 4 );
|
||||
|
||||
if ( !dcop_data_check_size( data, 4 ) )
|
||||
return FALSE;
|
||||
|
||||
*val = (data->cur[3] << 24) |
|
||||
(data->cur[2] << 16) |
|
||||
(data->cur[1] << 8) |
|
||||
data->cur[0];
|
||||
data->cur += 4;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
gboolean dcop_marshal_string( dcop_data *data, const gchar *str )
|
||||
{
|
||||
size_t l = 0;
|
||||
|
||||
if ( str )
|
||||
l = strlen( str ) + 1;
|
||||
|
||||
if( !dcop_marshal_uint32( data, l ) )
|
||||
return FALSE;
|
||||
|
||||
if ( str )
|
||||
return dcop_marshal_raw( data, str, l );
|
||||
else
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
gboolean dcop_demarshal_string( dcop_data *data, gchar **str )
|
||||
{
|
||||
unsigned int l = 0;
|
||||
gchar *res = 0;
|
||||
|
||||
g_assert( str );
|
||||
|
||||
if ( !dcop_demarshal_uint32( data, &l ) )
|
||||
return FALSE;
|
||||
|
||||
if ( !dcop_data_check_size( data, l ) )
|
||||
return FALSE;
|
||||
|
||||
res = (char *)g_malloc( l );
|
||||
memcpy( res, data->cur, l );
|
||||
data->cur += l;
|
||||
|
||||
*str = res;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
gboolean dcop_marshal_string16( dcop_data *data, const gchar *str )
|
||||
{
|
||||
size_t l = 0;
|
||||
size_t c = 0;
|
||||
char *tmp = 0;
|
||||
const char *src = str;
|
||||
char *dst = 0;
|
||||
|
||||
if ( str )
|
||||
l = strlen( str ) * 2;
|
||||
else
|
||||
{
|
||||
/* null marker*/
|
||||
guint32 s = 0xffffffff;
|
||||
return dcop_marshal_uint32( data, s );
|
||||
}
|
||||
|
||||
if( !dcop_marshal_uint32( data, l ) )
|
||||
return FALSE;
|
||||
|
||||
if ( str )
|
||||
{
|
||||
dst = tmp = (char *)g_malloc( l );
|
||||
c = strlen( str );
|
||||
|
||||
while ( c-- )
|
||||
{
|
||||
*dst++ = 0;
|
||||
*dst++ = *src++;
|
||||
}
|
||||
|
||||
dcop_marshal_raw( data, tmp, l );
|
||||
|
||||
g_free( tmp );
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
gboolean dcop_demarshal_string16( dcop_data *data, gchar **str )
|
||||
{
|
||||
unsigned int l = 0;
|
||||
unsigned int size = 0;
|
||||
char *res = 0;
|
||||
char *p = 0;
|
||||
|
||||
assert( str );
|
||||
|
||||
if ( !dcop_demarshal_uint32( data, &l ) )
|
||||
return FALSE;
|
||||
|
||||
/* null marker*/
|
||||
if ( l == 0xffffffff )
|
||||
{
|
||||
*str = 0;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
if ( !dcop_data_check_size( data, l ) )
|
||||
return FALSE;
|
||||
|
||||
size = ( l / 2 );
|
||||
|
||||
p = res = (char *)g_malloc( size + 1 );
|
||||
|
||||
while( size-- )
|
||||
{
|
||||
data->cur++;
|
||||
*p++ = *data->cur++;
|
||||
}
|
||||
|
||||
*p = '\0';
|
||||
|
||||
*str = res;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
gboolean dcop_marshal_bytearray( dcop_data *data, const gchar *str, size_t size )
|
||||
{
|
||||
if( !dcop_marshal_uint32( data, size ) )
|
||||
return FALSE;
|
||||
|
||||
if ( str )
|
||||
return dcop_marshal_raw( data, str, size );
|
||||
else
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
gboolean dcop_demarshal_bytearray( dcop_data *data, gchar **str, size_t *size )
|
||||
{
|
||||
unsigned int l = 0;
|
||||
gchar *res = 0;
|
||||
|
||||
g_assert( str );
|
||||
|
||||
if ( !dcop_demarshal_uint32( data, &l ) )
|
||||
return FALSE;
|
||||
|
||||
if ( !dcop_data_check_size( data, l ) )
|
||||
return FALSE;
|
||||
|
||||
res = (char *)g_malloc( l );
|
||||
memcpy( res, data->cur, l );
|
||||
data->cur += l;
|
||||
|
||||
*str = res;
|
||||
*size = l;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
|
||||
gboolean dcop_marshal_data( dcop_data *data, dcop_data *other )
|
||||
{
|
||||
if ( !dcop_marshal_uint32( data, other->size ) )
|
||||
return FALSE;
|
||||
|
||||
return dcop_marshal_raw( data, other->ptr, other->size );
|
||||
}
|
||||
|
||||
gboolean dcop_demarshal_data( dcop_data *data, dcop_data **other )
|
||||
{
|
||||
dcop_data *res = dcop_data_new();
|
||||
char *tmp = 0;
|
||||
unsigned int l = 0;
|
||||
|
||||
if ( !dcop_demarshal_uint32( data, &l ) )
|
||||
return FALSE;
|
||||
|
||||
if ( !dcop_data_check_size( data, l ) )
|
||||
return FALSE;
|
||||
|
||||
tmp = (char *)malloc( l );
|
||||
|
||||
memcpy( tmp, data->cur, l );
|
||||
data->cur += l;
|
||||
|
||||
dcop_data_assign( res, tmp, l );
|
||||
dcop_data_ref( res );
|
||||
|
||||
*other = res;
|
||||
return True;
|
||||
}
|
||||
|
||||
gboolean dcop_marshal_stringlist( dcop_data *data, GList *list )
|
||||
{
|
||||
GList *it = g_list_first( list );
|
||||
|
||||
if ( !dcop_marshal_uint32( data, g_list_length( list ) ) )
|
||||
return FALSE;
|
||||
|
||||
while ( it )
|
||||
{
|
||||
if ( !dcop_marshal_string( data, (gchar *)it->data ) )
|
||||
return FALSE;
|
||||
it = g_list_next( it );
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
gboolean dcop_demarshal_stringlist( dcop_data *data, GList**list )
|
||||
{
|
||||
unsigned int count = 0;
|
||||
GList *res = 0;
|
||||
unsigned int i = 0;
|
||||
gchar *str = 0;
|
||||
|
||||
*list = 0;
|
||||
|
||||
if ( !dcop_demarshal_uint32( data, &count ) )
|
||||
return FALSE;
|
||||
|
||||
for ( i = 0; i < count; ++i )
|
||||
{
|
||||
if ( !dcop_demarshal_string( data, &str ) )
|
||||
{
|
||||
dcop_list_free( res );
|
||||
return FALSE;
|
||||
}
|
||||
res = g_list_append( res, str );
|
||||
}
|
||||
*list = res;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
gboolean dcop_marshal_stringlist16( dcop_data *data, GList *list )
|
||||
{
|
||||
GList *it = g_list_first( list );
|
||||
|
||||
if ( !dcop_marshal_uint32( data, g_list_length( list ) ) )
|
||||
return False;
|
||||
|
||||
while ( it )
|
||||
{
|
||||
if ( !dcop_marshal_string16( data, (gchar *)it->data ) )
|
||||
return FALSE;
|
||||
it = g_list_next( it );
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
gboolean dcop_demarshal_stringlist16( dcop_data *data, GList **list )
|
||||
{
|
||||
unsigned int count = 0;
|
||||
GList *res = 0;
|
||||
unsigned int i = 0;
|
||||
char *str = 0;
|
||||
|
||||
*list = 0;
|
||||
|
||||
if ( !dcop_demarshal_uint32( data, &count ) )
|
||||
return FALSE;
|
||||
|
||||
for ( i = 0; i < count; ++i )
|
||||
{
|
||||
if ( !dcop_demarshal_string16( data, &str ) )
|
||||
{
|
||||
dcop_list_free( res );
|
||||
return FALSE;
|
||||
}
|
||||
res = g_list_append( res, str );
|
||||
}
|
||||
*list = res;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void dcop_data_assign( dcop_data *data, char *d, unsigned int size )
|
||||
{
|
||||
data->ptr = data->cur = d;
|
||||
data->size = size;
|
||||
}
|
||||
|
||||
gboolean dcop_marshal_boolean( dcop_data *data, gboolean val )
|
||||
{
|
||||
guint8 i = (guint8)val;
|
||||
return dcop_marshal_uint8( data, i );
|
||||
}
|
||||
|
||||
gboolean dcop_demarshal_boolean( dcop_data *data, gboolean *val )
|
||||
{
|
||||
guint8 i;
|
||||
if ( !dcop_demarshal_uint8( data, &i ) )
|
||||
return FALSE;
|
||||
*val = (gboolean)i;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
gboolean dcop_marshal_uint8( dcop_data *data, guint8 val )
|
||||
{
|
||||
return dcop_marshal_raw( data, &val, 1 );
|
||||
}
|
||||
|
||||
gboolean dcop_demarshal_uint8( dcop_data *data, guint8 *val )
|
||||
{
|
||||
if ( !dcop_data_check_size( data, 1 ) )
|
||||
return FALSE;
|
||||
|
||||
*val = *data->cur++;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
dcop_data *dcop_data_ref( dcop_data *data ) { data->ref++; return data; }
|
||||
void dcop_data_deref( dcop_data *data ) { if ( !--data->ref ) dcop_data_destroy( data ); }
|
||||
void dcop_data_reset( dcop_data *data ) { data->cur = data->ptr; }
|
@ -0,0 +1,93 @@
|
||||
/*
|
||||
Copyright (c) 2000 Simon Hausmann <hausmann@kde.org>
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
|
||||
AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
#ifndef __dcopc_marshal_h__
|
||||
#define __dcopc_marshal_h__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <X11/ICE/ICElib.h>
|
||||
|
||||
#include <dcopc/util.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
typedef struct _dcop_data dcop_data;
|
||||
|
||||
struct _dcop_data
|
||||
{
|
||||
char *ptr;
|
||||
unsigned int size;
|
||||
char *cur;
|
||||
unsigned int ref;
|
||||
};
|
||||
|
||||
/* remember to call ref() after this one! */
|
||||
dcop_data *dcop_data_new();
|
||||
|
||||
/* do not call directly! use deref! */
|
||||
void dcop_data_destroy( dcop_data *data );
|
||||
|
||||
void dcop_data_assign( dcop_data *data, char *d, unsigned int size );
|
||||
|
||||
dcop_data *dcop_data_ref( dcop_data *data );
|
||||
void dcop_data_deref( dcop_data *data );
|
||||
|
||||
dcop_data *dcop_data_copy( dcop_data *data );
|
||||
|
||||
void dcop_data_reset( dcop_data *data );
|
||||
|
||||
gboolean dcop_marshal_raw( dcop_data *data, const void *ptr, unsigned int size );
|
||||
|
||||
gboolean dcop_marshal_uint32( dcop_data *data, unsigned int val );
|
||||
gboolean dcop_demarshal_uint32( dcop_data *data, unsigned int *val );
|
||||
|
||||
gboolean dcop_marshal_string( dcop_data *data, const gchar *str );
|
||||
gboolean dcop_demarshal_string( dcop_data *data, gchar **str );
|
||||
|
||||
/* works only for ascii! */
|
||||
gboolean dcop_marshal_string16( dcop_data *data, const gchar *str );
|
||||
gboolean dcop_demarshal_string16( dcop_data *data, gchar **str );
|
||||
|
||||
gboolean dcop_marshal_bytearray( dcop_data *data, const gchar *str, size_t size );
|
||||
gboolean dcop_demarshal_bytearray( dcop_data *data, gchar **str, size_t *size );
|
||||
|
||||
gboolean dcop_marshal_data( dcop_data *data, dcop_data *other );
|
||||
gboolean dcop_demarshal_data( dcop_data *data, dcop_data **other );
|
||||
|
||||
gboolean dcop_marshal_stringlist( dcop_data *data, GList *list );
|
||||
gboolean dcop_demarshal_stringlist( dcop_data *data, GList **list );
|
||||
|
||||
gboolean dcop_marshal_stringlist16( dcop_data *data, GList *list );
|
||||
gboolean dcop_demarshal_stringlist16( dcop_data *data, GList **list );
|
||||
|
||||
gboolean dcop_marshal_boolean( dcop_data *data, gboolean val );
|
||||
gboolean dcop_demarshal_boolean( dcop_data *data, gboolean *val );
|
||||
|
||||
gboolean dcop_marshal_uint8( dcop_data *data, guint8 val );
|
||||
gboolean dcop_demarshal_uint8( dcop_data *data, guint8 *val );
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#endif
|
@ -0,0 +1,137 @@
|
||||
/*
|
||||
Copyright (c) 2000 Simon Hausmann <hausmann@kde.org>
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
|
||||
AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "util.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
|
||||
void dcop_stringlist_destroy( dcop_stringlist *list )
|
||||
{
|
||||
dcop_list_item *it = list->root;
|
||||
while ( it )
|
||||
{
|
||||
free( (char *)it->data );
|
||||
it = it->next;
|
||||
}
|
||||
dcop_list_destroy( list );
|
||||
}
|
||||
|
||||
void dcop_stringlist_append( dcop_stringlist *list, const char *str )
|
||||
{
|
||||
dcop_list_append( list, strdup( str ) );
|
||||
}
|
||||
|
||||
dcop_list *dcop_list_new()
|
||||
{
|
||||
dcop_list *res = (dcop_list *)malloc( sizeof( dcop_list ) );
|
||||
res->root = NULL;
|
||||
return res;
|
||||
}
|
||||
|
||||
void dcop_list_destroy( dcop_list *list )
|
||||
{
|
||||
dcop_list_item *it = list->root;
|
||||
while ( it )
|
||||
{
|
||||
dcop_list_item *tmp = it;
|
||||
it = it->next;
|
||||
free( tmp );
|
||||
}
|
||||
free( list );
|
||||
}
|
||||
|
||||
dcop_list_item *dcop_list_item_new()
|
||||
{
|
||||
dcop_list_item *res = malloc( sizeof( dcop_list ) );
|
||||
res->prev = res->next = NULL;
|
||||
return res;
|
||||
}
|
||||
|
||||
dcop_list_item *dcop_list_append( dcop_list *list, void *data )
|
||||
{
|
||||
dcop_list_item *it = list->root;
|
||||
dcop_list_item *res = dcop_list_item_new();
|
||||
|
||||
if ( it == NULL )
|
||||
list->root = res;
|
||||
else
|
||||
{
|
||||
while ( it->next != NULL )
|
||||
it = it->next;
|
||||
|
||||
it->next = res;
|
||||
res->prev = it;
|
||||
}
|
||||
|
||||
res->data = data;
|
||||
return res;
|
||||
}
|
||||
|
||||
gboolean dcop_list_remove( dcop_list *list, void *data )
|
||||
{
|
||||
dcop_list_item *it = list->root;
|
||||
|
||||
if ( it == NULL )
|
||||
return False;
|
||||
|
||||
if ( it->data == data )
|
||||
{
|
||||
list->root = it->next;
|
||||
if ( list->root )
|
||||
list->root->prev = NULL;
|
||||
|
||||
free( it );
|
||||
|
||||
return True;
|
||||
}
|
||||
|
||||
it = it->next;
|
||||
|
||||
while ( it != NULL )
|
||||
{
|
||||
if ( it->data == data )
|
||||
{
|
||||
it->prev->next = it->next;
|
||||
if ( it->next )
|
||||
it->next->prev = it->prev;
|
||||
free( it );
|
||||
return True;
|
||||
}
|
||||
it = it->next;
|
||||
}
|
||||
|
||||
return False;
|
||||
}
|
||||
|
||||
unsigned int dcop_list_count( dcop_list *list )
|
||||
{
|
||||
unsigned int res = 0;
|
||||
dcop_list_item *it = list->root;
|
||||
while ( it )
|
||||
{
|
||||
res++;
|
||||
it = it->next;
|
||||
}
|
||||
return res;
|
||||
}
|
@ -0,0 +1,73 @@
|
||||
/*
|
||||
Copyright (c) 2000 Simon Hausmann <hausmann@kde.org>
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
|
||||
AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
#ifndef __dcopc_util_h__
|
||||
#define __dcopc_util_h__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <X11/ICE/ICElib.h>
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
#define dcop_free( o ) \
|
||||
{ \
|
||||
g_free( o ); \
|
||||
o = 0; \
|
||||
}
|
||||
|
||||
#define dcop_string_assign( s, val ) \
|
||||
{ \
|
||||
dcop_free( s ); \
|
||||
if ( val != NULL ) \
|
||||
s = val; \
|
||||
}
|
||||
|
||||
#define dcop_string_copy( s, val ) \
|
||||
{ \
|
||||
dcop_free( s ); \
|
||||
if( val != NULL ) \
|
||||
s = g_strdup( val ); \
|
||||
}
|
||||
|
||||
#define dcop_string_assing( s, val ) \
|
||||
{ \
|
||||
dcop_free( s ); \
|
||||
if ( val != NULL ) \
|
||||
s = val; \
|
||||
}
|
||||
|
||||
#define dcop_list_free( lst ) \
|
||||
{ \
|
||||
GList *it = g_list_first( lst ); \
|
||||
while ( it ) \
|
||||
{ \
|
||||
g_free( it->data ); \
|
||||
it = g_list_next( it ); \
|
||||
} \
|
||||
g_list_free( lst ); \
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
@ -0,0 +1 @@
|
||||
SUBDIRS = binding dcopidl2java tests
|
@ -0,0 +1,16 @@
|
||||
lib_LTLIBRARIES = libjavadcop.la
|
||||
|
||||
libjavadcop_la_SOURCES = client.cpp
|
||||
libjavadcop_la_LDFLAGS = $(KDE_LDFLAGS) $(KDE_PLUGIN)
|
||||
libjavadcop_la_LIBADD = $(LIB_KDECORE)
|
||||
|
||||
INCLUDES = $(jni_includes) $(all_includes)
|
||||
|
||||
client.cpp: org_kde_DCOP_Client.h
|
||||
|
||||
org_kde_DCOP_Client.h: org/kde/DCOP/Client.class
|
||||
CLASSPATH=$(srcdir) $(JAVAH) -jni org.kde.DCOP.Client
|
||||
|
||||
SUBDIRS = org
|
||||
|
||||
CLEANFILES = org_kde_DCOP_Client.h
|
@ -0,0 +1,211 @@
|
||||
#include <stdio.h>
|
||||
#include <jni.h>
|
||||
#define TRUE true // prevent qglobal from redefining it
|
||||
#define FALSE false
|
||||
#include <dcopclient.h>
|
||||
#include <kdebug.h>
|
||||
|
||||
|
||||
#include "org_kde_DCOP_Client.h"
|
||||
|
||||
|
||||
class client
|
||||
{
|
||||
public:
|
||||
|
||||
static DCOPClient *instance();
|
||||
|
||||
private:
|
||||
|
||||
static DCOPClient *_client;
|
||||
|
||||
};
|
||||
|
||||
|
||||
DCOPClient *client::_client = 0;
|
||||
|
||||
|
||||
DCOPClient *client::instance()
|
||||
{
|
||||
if (!_client)
|
||||
_client = new DCOPClient;
|
||||
|
||||
return _client;
|
||||
}
|
||||
|
||||
|
||||
JNIEXPORT jboolean JNICALL Java_org_kde_DCOP_Client_attach(JNIEnv *, jobject)
|
||||
{
|
||||
kdDebug() << "javadcop::attach() called" << endl;
|
||||
|
||||
return client::instance()->attach();
|
||||
}
|
||||
|
||||
|
||||
JNIEXPORT jstring JNICALL Java_org_kde_DCOP_Client_registerAs(JNIEnv *env, jobject, jstring appName)
|
||||
{
|
||||
QString name(env->GetStringUTFChars(appName, 0));
|
||||
|
||||
kdDebug() << "javadcop::registerAs(\"" << name << "\") called" << endl;
|
||||
|
||||
QString rname = client::instance()->registerAs(name.local8Bit(), false);
|
||||
|
||||
return env->NewStringUTF(rname.local8Bit().data());
|
||||
}
|
||||
|
||||
|
||||
JNIEXPORT jboolean JNICALL Java_org_kde_DCOP_Client_isAttached(JNIEnv *, jobject)
|
||||
{
|
||||
kdDebug() << "javadcop::isAttached() called" << endl;
|
||||
|
||||
return client::instance()->isAttached();
|
||||
}
|
||||
|
||||
|
||||
JNIEXPORT jboolean JNICALL Java_org_kde_DCOP_Client_detach(JNIEnv *, jobject)
|
||||
{
|
||||
kdDebug() << "javadcop::detach() called" << endl;
|
||||
|
||||
return client::instance()->detach();
|
||||
}
|
||||
|
||||
|
||||
JNIEXPORT jboolean JNICALL Java_org_kde_DCOP_Client_send__Ljava_lang_String_2Ljava_lang_String_2Ljava_lang_String_2Ljava_lang_String_2(JNIEnv *env, jobject, jstring remApp, jstring remObj, jstring remFun, jstring data)
|
||||
{
|
||||
QString _remApp(env->GetStringUTFChars(remApp, 0));
|
||||
QString _remObj(env->GetStringUTFChars(remObj, 0));
|
||||
QString _remFun(env->GetStringUTFChars(remFun, 0));
|
||||
QString _data(env->GetStringUTFChars(data, 0));
|
||||
|
||||
kdDebug() << "javadcop::send(" << _remApp << "," << _remObj << "," << _remFun << "," << _data << "," <<") called" << endl;
|
||||
|
||||
return client::instance()->send(_remApp.local8Bit(), _remObj.local8Bit(), _remFun.local8Bit(), _data.local8Bit());
|
||||
}
|
||||
|
||||
|
||||
QByteArray byteArray(JNIEnv *env, jbyteArray a)
|
||||
{
|
||||
jsize len = env->GetArrayLength(a);
|
||||
QByteArray _data(len);
|
||||
jboolean isCopy;
|
||||
_data.duplicate((const char *)env->GetByteArrayElements(a, &isCopy), len);
|
||||
|
||||
return _data;
|
||||
}
|
||||
|
||||
|
||||
JNIEXPORT jboolean JNICALL Java_org_kde_DCOP_Client_send__Ljava_lang_String_2Ljava_lang_String_2Ljava_lang_String_2_3B(JNIEnv *env, jobject, jstring remApp, jstring remObj, jstring remFun, jbyteArray data)
|
||||
{
|
||||
QString _remApp(env->GetStringUTFChars(remApp, 0));
|
||||
QString _remObj(env->GetStringUTFChars(remObj, 0));
|
||||
QString _remFun(env->GetStringUTFChars(remFun, 0));
|
||||
QByteArray _data = byteArray(env, data);
|
||||
|
||||
kdDebug() << "javadcop::send(" << _remApp << "," << _remObj << "," << _remFun << ", data[" << _data.size() << "], " <<") called" << endl;
|
||||
for (uint i=0; i<_data.size(); ++i)
|
||||
kdDebug() << " data[" << i << "] = " << _data[i] << endl;
|
||||
|
||||
return client::instance()->send(_remApp.local8Bit(), _remObj.local8Bit(), _remFun.local8Bit(), _data);
|
||||
}
|
||||
|
||||
|
||||
JNIEXPORT jboolean JNICALL Java_org_kde_DCOP_Client_isRegistered(JNIEnv *, jobject)
|
||||
{
|
||||
kdDebug() << "javadcop::isRegistered() called" << endl;
|
||||
|
||||
return client::instance()->isRegistered();
|
||||
}
|
||||
|
||||
|
||||
JNIEXPORT jstring JNICALL Java_org_kde_DCOP_Client_appId(JNIEnv *env, jobject)
|
||||
{
|
||||
kdDebug() << "javadcop::appId called" << endl;
|
||||
|
||||
return env->NewStringUTF(client::instance()->appId().data());
|
||||
}
|
||||
|
||||
|
||||
JNIEXPORT void JNICALL Java_org_kde_DCOP_Client_suspend(JNIEnv *, jobject)
|
||||
{
|
||||
kdDebug() << "javadcop::suspend() called" << endl;
|
||||
|
||||
client::instance()->suspend();
|
||||
}
|
||||
|
||||
|
||||
JNIEXPORT void JNICALL Java_org_kde_DCOP_Client_resume(JNIEnv *, jobject)
|
||||
{
|
||||
kdDebug() << "javadcop::resume() called" << endl;
|
||||
|
||||
client::instance()->resume();
|
||||
}
|
||||
|
||||
|
||||
JNIEXPORT jobject JNICALL Java_org_kde_DCOP_Client_call(JNIEnv *env, jobject, jstring remApp, jstring remObj, jstring remFun, jbyteArray data, jboolean eventLoop)
|
||||
{
|
||||
QString _remApp(env->GetStringUTFChars(remApp, 0));
|
||||
QString _remObj(env->GetStringUTFChars(remObj, 0));
|
||||
QString _remFun(env->GetStringUTFChars(remFun, 0));
|
||||
QByteArray _data = byteArray(env, data);
|
||||
|
||||
kdDebug() << "javadcop::call(" << _remApp << "," << _remObj << "," << _remFun << ", data[" << _data.size() << "], " << eventLoop <<") called" << endl;
|
||||
for (uint i=0; i<_data.size(); ++i)
|
||||
kdDebug() << " data[" << i << "] = " << _data[i] << endl;
|
||||
|
||||
QCString _retType;
|
||||
QByteArray _retData;
|
||||
bool retval = client::instance()->call(_remApp.local8Bit(), _remObj.local8Bit(), _remFun.local8Bit(), _data, _retType, _retData, eventLoop);
|
||||
|
||||
kdDebug() << "Return type " << _retType << endl;
|
||||
|
||||
for (uint i=0; i<_retData.size(); ++i)
|
||||
kdDebug() << " retData[" << i << "] = " << _retData[i] << endl;
|
||||
|
||||
// create a response object
|
||||
jclass jcls;
|
||||
jmethodID jmid;
|
||||
jobject response;
|
||||
jfieldID jfid;
|
||||
|
||||
jcls = env->FindClass("Lorg/kde/DCOP/Response;");
|
||||
if (!jcls)
|
||||
return NULL;
|
||||
|
||||
jmid = env->GetMethodID(jcls, "<init>", "()V");
|
||||
if (!jmid)
|
||||
return NULL;
|
||||
|
||||
response = env->NewObject(jcls, jmid);
|
||||
if (!response)
|
||||
return NULL;
|
||||
|
||||
jfid = env->GetFieldID(jcls, "returnType", "Ljava/lang/String;");
|
||||
if (!jfid)
|
||||
return NULL;
|
||||
env->SetObjectField(response, jfid, env->NewStringUTF(_retType.data()));
|
||||
|
||||
jfid = env->GetFieldID(jcls, "returnValue", "Z");
|
||||
if (!jfid)
|
||||
return NULL;
|
||||
env->SetBooleanField(response, jfid, retval);
|
||||
|
||||
jfid = env->GetFieldID(jcls, "returnData", "[B");
|
||||
if (!jfid)
|
||||
return NULL;
|
||||
jbyteArray ba = env->NewByteArray(_retData.size());
|
||||
env->SetByteArrayRegion(ba, 0, _retData.size(), (jbyte*) _retData.data());
|
||||
env->SetObjectField(response, jfid, ba);
|
||||
|
||||
// return the response object
|
||||
kdDebug() << "response object created" << endl;
|
||||
return response;
|
||||
}
|
||||
|
||||
JNIEXPORT jboolean JNICALL Java_org_kde_DCOP_Client_isApplicationRegistered(JNIEnv *env, jobject, jstring remApp)
|
||||
{
|
||||
const QCString _remApp(env->GetStringUTFChars(remApp, 0));
|
||||
|
||||
kdDebug() << "javadcop::isApplicationRegistered() called" << endl;
|
||||
|
||||
return client::instance()->isApplicationRegistered(_remApp);
|
||||
}
|
@ -0,0 +1 @@
|
||||
SUBDIRS = kde
|
@ -0,0 +1,63 @@
|
||||
package org.kde.DCOP;
|
||||
|
||||
|
||||
public class Client
|
||||
{
|
||||
// attach to DCOP server as 'anonymous'
|
||||
public native boolean attach();
|
||||
|
||||
// attach to DCOP server using appName as key
|
||||
public native String registerAs(String appName);
|
||||
|
||||
// report if we are registered at the server
|
||||
public native boolean isRegistered();
|
||||
|
||||
// return the registered application id
|
||||
public native String appId();
|
||||
|
||||
// suspend DCOP processing
|
||||
public native void suspend();
|
||||
|
||||
// resume DCOP processing
|
||||
public native void resume();
|
||||
|
||||
// detach from the DCOP server
|
||||
public native boolean detach();
|
||||
|
||||
// report if we are attached to DCOP server
|
||||
public native boolean isAttached();
|
||||
|
||||
// send a command to the server
|
||||
public native boolean send(String remApp, String remObj, String remFun, byte[] data);
|
||||
|
||||
// send a command string to the server
|
||||
public native boolean send(String remApp, String remObj, String remFun, String data);
|
||||
|
||||
// call a function and get the result
|
||||
public native Response call(String remApp, String remObj, String remFun, byte[] data, boolean eventLoop);
|
||||
|
||||
// Checks whether remApp is registered with the DCOP server.
|
||||
public native boolean isApplicationRegistered ( String remApp);
|
||||
|
||||
public static void main(String[] args)
|
||||
{
|
||||
Client client = new Client();
|
||||
|
||||
System.out.println("Registering as: " + client.registerAs("Java-App"));
|
||||
if (client.isAttached())
|
||||
System.out.println("Attached!");
|
||||
|
||||
client.send("kdesktop", "KDesktopIface", "selectAll()", "");
|
||||
|
||||
java.io.ByteArrayOutputStream bs = new java.io.ByteArrayOutputStream();
|
||||
Response res = client.call("kdesktop", "KDesktopIface", "selectedURLs()", bs.toByteArray(), false);
|
||||
System.out.println("Result type: " + res.returnType);
|
||||
}
|
||||
|
||||
static
|
||||
{
|
||||
System.loadLibrary("javadcop");
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -0,0 +1,30 @@
|
||||
package org.kde.DCOP;
|
||||
|
||||
|
||||
public class DCOPRef
|
||||
{
|
||||
private String _app, _obj, _type;
|
||||
|
||||
public DCOPRef(String app, String obj, String type)
|
||||
{
|
||||
_app = app;
|
||||
_obj = obj;
|
||||
_type = type;
|
||||
}
|
||||
|
||||
public String app()
|
||||
{
|
||||
return _app;
|
||||
}
|
||||
|
||||
public String object()
|
||||
{
|
||||
return _obj;
|
||||
}
|
||||
|
||||
public String type()
|
||||
{
|
||||
return _type;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,9 @@
|
||||
class_DATA = DCOPRef.class Response.class Client.class Stub.class Response.class
|
||||
classdir = $(kde_libraries)/java/org/kde/DCOP
|
||||
|
||||
SUFFIXES = .java .class
|
||||
|
||||
.java.class:
|
||||
CLASSPATH=$(top_srcdir)/dcopjava/binding $(JAVAC) -d ../../../ -cp ../../../ $(top_srcdir)/dcopjava/binding/org/kde/DCOP/$*.java
|
||||
|
||||
CLEANFILES = $(class_DATA)
|
@ -0,0 +1,9 @@
|
||||
package org.kde.DCOP;
|
||||
|
||||
|
||||
public class Response
|
||||
{
|
||||
public boolean returnValue;
|
||||
public String returnType;
|
||||
public byte[] returnData;
|
||||
}
|
@ -0,0 +1,193 @@
|
||||
package org.kde.DCOP;
|
||||
|
||||
|
||||
import java.io.*;
|
||||
|
||||
|
||||
public class Stub
|
||||
{
|
||||
private String _app, _obj;
|
||||
private int _status;
|
||||
private Client _client;
|
||||
|
||||
public Stub(String app, String obj)
|
||||
{
|
||||
_app = app;
|
||||
_obj = obj;
|
||||
_status = 0;
|
||||
|
||||
// TODO: The client should be shared between stubs.
|
||||
_client = new Client();
|
||||
_client.attach();
|
||||
}
|
||||
|
||||
public String app()
|
||||
{
|
||||
return _app;
|
||||
}
|
||||
|
||||
public String obj()
|
||||
{
|
||||
return _obj;
|
||||
}
|
||||
|
||||
|
||||
public Client client()
|
||||
{
|
||||
return _client;
|
||||
}
|
||||
|
||||
|
||||
public final static int CallFailed = 0;
|
||||
public final static int CallSucceeded = 1;
|
||||
|
||||
public int status()
|
||||
{
|
||||
return _status;
|
||||
}
|
||||
|
||||
public void setStatus(int status)
|
||||
{
|
||||
_status = status;
|
||||
}
|
||||
|
||||
public boolean ok()
|
||||
{
|
||||
return _status == CallSucceeded;
|
||||
}
|
||||
|
||||
public void callFailed()
|
||||
{
|
||||
_status = CallFailed;
|
||||
}
|
||||
|
||||
|
||||
// accessor methods for the datatypes used ---------------------------
|
||||
|
||||
protected boolean read_bool(DataInputStream is) throws IOException
|
||||
{
|
||||
return is.readBoolean();
|
||||
}
|
||||
|
||||
protected void write_bool(DataOutputStream os, boolean val) throws IOException
|
||||
{
|
||||
os.writeBoolean(val);
|
||||
}
|
||||
|
||||
protected short read_short_int(DataInputStream is) throws IOException
|
||||
{
|
||||
return is.readShort();
|
||||
}
|
||||
|
||||
protected void write_short_int(DataOutputStream os, short val) throws IOException
|
||||
{
|
||||
os.writeShort(val);
|
||||
}
|
||||
|
||||
protected int read_int(DataInputStream is) throws IOException
|
||||
{
|
||||
return is.readInt();
|
||||
}
|
||||
|
||||
protected void write_int(DataOutputStream os, int val) throws IOException
|
||||
{
|
||||
os.writeInt(val);
|
||||
}
|
||||
|
||||
protected int read_long_int(DataInputStream is) throws IOException
|
||||
{
|
||||
return is.readInt();
|
||||
}
|
||||
|
||||
protected void write_long_int(DataOutputStream os, int val) throws IOException
|
||||
{
|
||||
os.writeInt(val);
|
||||
}
|
||||
|
||||
protected float read_float(DataInputStream is) throws IOException
|
||||
{
|
||||
return is.readFloat();
|
||||
}
|
||||
|
||||
protected void write_float(DataOutputStream os, float val) throws IOException
|
||||
{
|
||||
os.writeFloat(val);
|
||||
}
|
||||
|
||||
protected double read_double(DataInputStream is) throws IOException
|
||||
{
|
||||
return is.readDouble();
|
||||
}
|
||||
|
||||
protected void write_double(DataOutputStream os, double val) throws IOException
|
||||
{
|
||||
os.writeDouble(val);
|
||||
}
|
||||
|
||||
protected String read_QString(DataInputStream is) throws IOException
|
||||
{
|
||||
int len = is.readInt();
|
||||
if (len == 0xffffffff)
|
||||
return new String();
|
||||
else
|
||||
{
|
||||
StringBuffer b = new StringBuffer();
|
||||
for (int i=0; i<len/2; ++i)
|
||||
b.append(is.readChar());
|
||||
return b.toString();
|
||||
}
|
||||
}
|
||||
|
||||
protected void write_QString(DataOutputStream os, String val) throws IOException
|
||||
{
|
||||
os.writeInt(val.length()*2);
|
||||
for (int i=0; i<val.length(); ++i)
|
||||
os.writeChar(val.charAt(i));
|
||||
}
|
||||
|
||||
protected String read_QCString(DataInputStream is) throws IOException
|
||||
{
|
||||
int len = is.readInt();
|
||||
StringBuffer b = new StringBuffer();
|
||||
for (int i=0; i<len; ++i)
|
||||
b.append((char)is.readByte());
|
||||
return b.toString();
|
||||
}
|
||||
|
||||
protected void write_QCString(DataOutputStream os, String val) throws IOException
|
||||
{
|
||||
os.writeInt(val.length()+1);
|
||||
for (int i=0; i<val.length(); ++i)
|
||||
os.writeByte(val.charAt(i));
|
||||
os.writeByte(0);
|
||||
}
|
||||
|
||||
protected String[] read_QStringList(DataInputStream is) throws IOException
|
||||
{
|
||||
int n = is.readInt();
|
||||
String[] result = new String[n];
|
||||
for (int i=0; i<n; ++i)
|
||||
result[i] = read_QString(is);
|
||||
return result;
|
||||
}
|
||||
|
||||
protected void write_QStringList(DataOutputStream os, String[] val) throws IOException
|
||||
{
|
||||
os.writeInt(val.length);
|
||||
for (int i=0; i<val.length; ++i)
|
||||
write_QCString(os, val[i]);
|
||||
}
|
||||
|
||||
protected void write_DCOPRef(DataOutputStream os, DCOPRef ref) throws IOException
|
||||
{
|
||||
write_QCString(os, ref.app());
|
||||
write_QCString(os, ref.object());
|
||||
write_QCString(os, ref.type());
|
||||
}
|
||||
|
||||
protected DCOPRef read_DCOPRef(DataInputStream is) throws IOException
|
||||
{
|
||||
return new DCOPRef(read_QCString(is), read_QCString(is), read_QCString(is));
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1 @@
|
||||
SUBDIRS = DCOP
|
@ -0,0 +1,2 @@
|
||||
KDE_CHECK_JAVA([dcopjava])
|
||||
|
@ -0,0 +1,11 @@
|
||||
|
||||
INCLUDES = $(all_includes)
|
||||
|
||||
bin_PROGRAMS = dcopidl2java
|
||||
|
||||
dcopidl2java_SOURCES = main.cpp skel.cpp stubimpl.cpp
|
||||
noinst_HEADERS = main.h
|
||||
|
||||
dcopidl2java_LDADD = $(LIB_QT)
|
||||
dcopidl2java_LDFLAGS = $(all_libraries) $(KDE_RPATH)
|
||||
|
@ -0,0 +1,110 @@
|
||||
/*****************************************************************
|
||||
Copyright (c) 1999 Torben Weis <weis@kde.org>
|
||||
Copyright (c) 2000 Matthias Ettrich <ettrich@kde.org>
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
|
||||
AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
******************************************************************/
|
||||
#include <qdom.h>
|
||||
#include <qfile.h>
|
||||
#include <qtextstream.h>
|
||||
#include <qstring.h>
|
||||
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include "main.h"
|
||||
|
||||
|
||||
|
||||
void usage()
|
||||
{
|
||||
fprintf( stderr, "Usage: dcopidl2java [ --no-skel | --no-stub | --package java-package ] file\n" );
|
||||
}
|
||||
|
||||
int main( int argc, char** argv )
|
||||
{
|
||||
|
||||
if ( *qVersion() == '1' ) {
|
||||
fprintf( stderr, "dcopidl2cpp appears to be linked to Qt 1 instead of Qt 2 ! Aborting.\n" );
|
||||
exit(1);
|
||||
}
|
||||
int argpos = 1;
|
||||
bool generate_skel = TRUE;
|
||||
bool generate_stub = TRUE;
|
||||
QString package;
|
||||
|
||||
while (argc > 2) {
|
||||
|
||||
if ( strcmp( argv[argpos], "--no-skel" ) == 0 )
|
||||
{
|
||||
generate_skel = FALSE;
|
||||
for (int i = argpos; i < argc - 1; i++) argv[i] = argv[i+1];
|
||||
argc--;
|
||||
}
|
||||
else if ( strcmp( argv[argpos], "--no-stub" ) == 0 )
|
||||
{
|
||||
generate_stub = FALSE;
|
||||
for (int i = argpos; i < argc - 1; i++) argv[i] = argv[i+1];
|
||||
argc--;
|
||||
}
|
||||
else if ( strcmp( argv[argpos], "--package" ) == 0 )
|
||||
{
|
||||
if (argpos + 1 < argc)
|
||||
package = QString(argv[argpos+1]);
|
||||
|
||||
for (int i = argpos; i < argc - 2; i++) argv[i] = argv[i+2];
|
||||
argc -= 2;
|
||||
} else {
|
||||
usage();
|
||||
exit(1);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
QFile in( argv[argpos] );
|
||||
if ( !in.open( IO_ReadOnly ) )
|
||||
qFatal("Could not read %s", argv[argpos] );
|
||||
|
||||
QDomDocument doc;
|
||||
doc.setContent( &in );
|
||||
|
||||
QDomElement de = doc.documentElement();
|
||||
ASSERT( de.tagName() == "DCOP-IDL" );
|
||||
|
||||
QString base( argv[argpos] );
|
||||
QString idl = base;
|
||||
|
||||
int pos = base.findRev( '.' );
|
||||
if ( pos != -1 )
|
||||
base = base.left( pos );
|
||||
|
||||
pos = idl.findRev('/');
|
||||
if ( pos != -1 )
|
||||
idl = idl.mid( pos+1 );
|
||||
|
||||
if ( generate_skel )
|
||||
;// generateSkel( idl, base + "_skel.java", de );
|
||||
|
||||
if ( generate_stub ) {
|
||||
generateStubImpl( idl, package, base + "_stub.java", de );
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
@ -0,0 +1,35 @@
|
||||
/*****************************************************************
|
||||
Copyright (c) 1999 Torben Weis <weis@kde.org>
|
||||
Copyright (c) 2000 Matthias Ettrich <ettrich@kde.org>
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
|
||||
AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
******************************************************************/
|
||||
#include <qdom.h>
|
||||
#include <qstring.h>
|
||||
|
||||
/**
|
||||
* Writes the skeleton
|
||||
*/
|
||||
void generateSkel( const QString& idl, const QString& filename, QDomElement de );
|
||||
|
||||
/**
|
||||
* Writes the stub implementation
|
||||
*/
|
||||
void generateStubImpl( const QString& idl, const QString& package, const QString& filename, QDomElement de );
|
||||
|
@ -0,0 +1,322 @@
|
||||
/*****************************************************************
|
||||
Copyright (c) 1999 Torben Weis <weis@kde.org>
|
||||
Copyright (c) 2000 Matthias Ettrich <ettrich@kde.org>
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
|
||||
AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
******************************************************************/
|
||||
#include <qdom.h>
|
||||
#include <qfile.h>
|
||||
#include <qtextstream.h>
|
||||
#include <qstring.h>
|
||||
#include <qvaluelist.h>
|
||||
#include <qstringlist.h>
|
||||
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include "main.h"
|
||||
|
||||
static int const primes[] =
|
||||
{
|
||||
2, 3, 5, 7, 11, 13, 17, 19, 23, 29,
|
||||
31, 37, 41, 43, 47, 53, 59, 61, 67, 71,
|
||||
73, 79, 83, 89, 97, 101, 103, 107, 109, 113,
|
||||
127, 131, 137, 139, 149, 151, 157, 163, 167, 173,
|
||||
179, 181, 191, 193, 197, 199, 211, 223, 227, 229,
|
||||
233, 239, 241, 251, 257, 263, 269, 271, 277, 281,
|
||||
283, 293, 307, 311, 313, 317, 331, 337, 347, 349,
|
||||
353, 359, 367, 373, 379, 383, 389, 397, 401, 409,
|
||||
419, 421, 431, 433, 439, 443, 449, 457, 461, 463,
|
||||
467, 479, 487, 491, 499, 503, 509, 521, 523, 541,
|
||||
547, 557, 563, 569, 571, 577, 587, 593, 599, 601,0
|
||||
};
|
||||
|
||||
|
||||
struct Function
|
||||
{
|
||||
Function(){};
|
||||
Function( const QString& t, const QString& n, const QString&fn ) : type( t ), name( n ), fullName( fn ){}
|
||||
QString type;
|
||||
QString name;
|
||||
QString fullName;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Writes the skeleton
|
||||
*/
|
||||
void generateSkel( const QString& idl, const QString& filename, QDomElement de )
|
||||
{
|
||||
QFile skel( filename );
|
||||
if ( !skel.open( IO_WriteOnly ) )
|
||||
qFatal("Could not write to %s", filename.latin1() );
|
||||
|
||||
QTextStream str( &skel );
|
||||
|
||||
str << "/****************************************************************************" << endl;
|
||||
str << "**" << endl;
|
||||
str << "** DCOP Skeleton created by dcopidl2cpp from " << idl << endl;
|
||||
str << "**" << endl;
|
||||
str << "** WARNING! All changes made in this file will be lost!" << endl;
|
||||
str << "**" << endl;
|
||||
str << "*****************************************************************************/" << endl;
|
||||
str << endl;
|
||||
|
||||
QDomElement e = de.firstChild().toElement();
|
||||
if ( e.tagName() == "SOURCE" ) {
|
||||
str << "#include \"" << e.firstChild().toText().data() << "\"" << endl << endl;
|
||||
}
|
||||
|
||||
for( ; !e.isNull(); e = e.nextSibling().toElement() ) {
|
||||
if ( e.tagName() == "CLASS" ) {
|
||||
QDomElement n = e.firstChild().toElement();
|
||||
ASSERT( n.tagName() == "NAME" );
|
||||
QString className = n.firstChild().toText().data();
|
||||
// find dcop parent ( rightmost super class )
|
||||
QString DCOPParent;
|
||||
QDomElement s = n.nextSibling().toElement();
|
||||
for( ; !s.isNull(); s = s.nextSibling().toElement() ) {
|
||||
if ( s.tagName() == "SUPER" )
|
||||
DCOPParent = s.firstChild().toText().data();
|
||||
}
|
||||
|
||||
// get function table
|
||||
QValueList<Function> functions;
|
||||
s = n.nextSibling().toElement();
|
||||
for( ; !s.isNull(); s = s.nextSibling().toElement() ) {
|
||||
if ( s.tagName() == "FUNC" ) {
|
||||
QDomElement r = s.firstChild().toElement();
|
||||
ASSERT( r.tagName() == "TYPE" );
|
||||
QString funcType = r.firstChild().toText().data();
|
||||
r = r.nextSibling().toElement();
|
||||
ASSERT ( r.tagName() == "NAME" );
|
||||
QString funcName = r.firstChild().toText().data();
|
||||
QStringList argtypes;
|
||||
QStringList argnames;
|
||||
r = r.nextSibling().toElement();
|
||||
for( ; !r.isNull(); r = r.nextSibling().toElement() ) {
|
||||
ASSERT( r.tagName() == "ARG" );
|
||||
QDomElement a = r.firstChild().toElement();
|
||||
ASSERT( a.tagName() == "TYPE" );
|
||||
argtypes.append( a.firstChild().toText().data() );
|
||||
a = a.nextSibling().toElement();
|
||||
if ( !a.isNull() ) {
|
||||
ASSERT( a.tagName() == "NAME" );
|
||||
argnames.append( a.firstChild().toText().data() );
|
||||
} else {
|
||||
argnames.append( QString::null );
|
||||
}
|
||||
}
|
||||
funcName += '(';
|
||||
QString fullFuncName = funcName;
|
||||
bool first = TRUE;
|
||||
QStringList::Iterator ittype = argtypes.begin();
|
||||
QStringList::Iterator itname = argnames.begin();
|
||||
while ( ittype != argtypes.end() && itname != argnames.end() ) {
|
||||
if ( !first ) {
|
||||
funcName += ',';
|
||||
fullFuncName += ',';
|
||||
}
|
||||
first = FALSE;
|
||||
funcName += *ittype;
|
||||
fullFuncName += *ittype;
|
||||
if ( ! (*itname).isEmpty() ) {
|
||||
fullFuncName += ' ';
|
||||
fullFuncName += *itname;
|
||||
}
|
||||
++ittype;
|
||||
++itname;
|
||||
}
|
||||
funcName += ')';
|
||||
fullFuncName += ')';
|
||||
functions.append( Function( funcType, funcName, fullFuncName ) );
|
||||
}
|
||||
}
|
||||
|
||||
// create static tables
|
||||
|
||||
int fhash = functions.count() + 1;
|
||||
for ( int i = 0; primes[i]; i++ ) {
|
||||
if ( primes[i] > static_cast<int>(functions.count()) ) {
|
||||
fhash = primes[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
str << "#include <kdatastream.h>" << endl;
|
||||
|
||||
bool useHashing = functions.count() > 7;
|
||||
if ( useHashing ) {
|
||||
str << "#include <qasciidict.h>" << endl;
|
||||
str << "static const int " << className << "_fhash = " << fhash << ";" << endl;
|
||||
}
|
||||
str << "static const char* const " << className << "_ftable[" << functions.count() + 1 << "][3] = {" << endl;
|
||||
for( QValueList<Function>::Iterator it = functions.begin(); it != functions.end(); ++it ){
|
||||
str << " { \"" << (*it).type << "\", \"" << (*it).name << "\", \"" << (*it).fullName << "\" }," << endl;
|
||||
}
|
||||
str << " { 0, 0, 0 }" << endl;
|
||||
str << "};" << endl;
|
||||
|
||||
str << endl;
|
||||
|
||||
|
||||
// Write dispatcher
|
||||
str << "bool " << className;
|
||||
str << "::process(const QCString &fun, const QByteArray &data, QCString& replyType, QByteArray &replyData)" << endl;
|
||||
str << "{" << endl;
|
||||
if ( useHashing ) {
|
||||
str << " static QAsciiDict<int>* fdict = 0;" << endl;
|
||||
|
||||
str << " if ( !fdict ) {" << endl;
|
||||
str << "\tfdict = new QAsciiDict<int>( " << className << "_fhash, TRUE, FALSE );" << endl;
|
||||
str << "\tfor ( int i = 0; " << className << "_ftable[i][1]; i++ )" << endl;
|
||||
str << "\t fdict->insert( " << className << "_ftable[i][1], new int( i ) );" << endl;
|
||||
str << " }" << endl;
|
||||
|
||||
str << " int* fp = fdict->find( fun );" << endl;
|
||||
str << " switch ( fp?*fp:-1) {" << endl;
|
||||
}
|
||||
s = n.nextSibling().toElement();
|
||||
int fcount = 0;
|
||||
bool firstFunc = TRUE;
|
||||
for( ; !s.isNull(); s = s.nextSibling().toElement() ) {
|
||||
if ( s.tagName() == "FUNC" ) {
|
||||
QDomElement r = s.firstChild().toElement();
|
||||
ASSERT( r.tagName() == "TYPE" );
|
||||
QString funcType = r.firstChild().toText().data();
|
||||
if ( funcType == "ASYNC" )
|
||||
funcType = "void";
|
||||
r = r.nextSibling().toElement();
|
||||
ASSERT ( r.tagName() == "NAME" );
|
||||
QString funcName = r.firstChild().toText().data();
|
||||
QStringList args;
|
||||
QStringList argtypes;
|
||||
r = r.nextSibling().toElement();
|
||||
for( ; !r.isNull(); r = r.nextSibling().toElement() ) {
|
||||
ASSERT( r.tagName() == "ARG" );
|
||||
QDomElement a = r.firstChild().toElement();
|
||||
ASSERT( a.tagName() == "TYPE" );
|
||||
argtypes.append( a.firstChild().toText().data() );
|
||||
args.append( QString("arg" ) + QString::number( args.count() ) );
|
||||
}
|
||||
QString plainFuncName = funcName;
|
||||
funcName += '(';
|
||||
bool first = TRUE;
|
||||
for( QStringList::Iterator argtypes_count = argtypes.begin(); argtypes_count != argtypes.end(); ++argtypes_count ){
|
||||
if ( !first )
|
||||
funcName += ',';
|
||||
first = FALSE;
|
||||
funcName += *argtypes_count;
|
||||
}
|
||||
funcName += ')';
|
||||
|
||||
if ( useHashing ) {
|
||||
str << " case " << fcount << ": { // " << funcType << " " << funcName << endl;
|
||||
} else {
|
||||
if ( firstFunc )
|
||||
str << " if ( fun == " << className << "_ftable[" << fcount << "][1] ) { // " << funcType << " " << funcName << endl;
|
||||
else
|
||||
str << " else if ( fun == " << className << "_ftable[" << fcount << "][1] ) { // " << funcType << " " << funcName << endl;
|
||||
firstFunc = FALSE;
|
||||
}
|
||||
if ( !args.isEmpty() ) {
|
||||
QStringList::Iterator ittypes = argtypes.begin();
|
||||
QStringList::Iterator args_count;
|
||||
for( args_count = args.begin(); args_count != args.end(); ++args_count ){
|
||||
str << '\t'<< *ittypes << " " << *args_count << ";" << endl;
|
||||
++ittypes;
|
||||
}
|
||||
str << "\tQDataStream arg( data, IO_ReadOnly );" << endl;
|
||||
for( args_count = args.begin(); args_count != args.end(); ++args_count ){
|
||||
str << "\targ >> " << *args_count << ";" << endl;
|
||||
}
|
||||
}
|
||||
|
||||
str << "\treplyType = " << className << "_ftable[" << fcount++ << "][0]; " << endl;
|
||||
if ( funcType == "void" ) {
|
||||
str << '\t' << plainFuncName << '(';
|
||||
} else {
|
||||
str << "\tQDataStream _replyStream( replyData, IO_WriteOnly );" << endl;
|
||||
str << "\t_replyStream << " << plainFuncName << '(';
|
||||
}
|
||||
|
||||
first = TRUE;
|
||||
for ( QStringList::Iterator args_count = args.begin(); args_count != args.end(); ++args_count ){
|
||||
if ( !first )
|
||||
str << ", ";
|
||||
first = FALSE;
|
||||
str << *args_count;
|
||||
}
|
||||
str << " );" << endl;
|
||||
if (useHashing ) {
|
||||
str << " } break;" << endl;
|
||||
} else {
|
||||
str << " }";
|
||||
}
|
||||
}
|
||||
}
|
||||
if ( useHashing ) {
|
||||
str << " default: " << endl;
|
||||
} else {
|
||||
str << " else {" << endl;
|
||||
}
|
||||
if (!DCOPParent.isEmpty()) {
|
||||
str << "\treturn " << DCOPParent << "::process( fun, data, replyType, replyData );" << endl;
|
||||
} else {
|
||||
str << "\treturn FALSE;" << endl;
|
||||
}
|
||||
str << " }" << endl;
|
||||
str << " return TRUE;" << endl;
|
||||
str << "}" << endl << endl;
|
||||
|
||||
str << "QCStringList " << className;
|
||||
str << "::interfaces()" << endl;
|
||||
str << "{" << endl;
|
||||
if (!DCOPParent.isEmpty()) {
|
||||
str << " QCStringList ifaces = " << DCOPParent << "::interfaces();" << endl;
|
||||
} else {
|
||||
str << " QCStringList ifaces;" << endl;
|
||||
}
|
||||
str << " ifaces += \"" << className << "\";" << endl;
|
||||
str << " return ifaces;" << endl;
|
||||
str << "}" << endl << endl;
|
||||
|
||||
|
||||
str << "QCStringList " << className;
|
||||
str << "::functions()" << endl;
|
||||
str << "{" << endl;
|
||||
if (!DCOPParent.isEmpty()) {
|
||||
str << " QCStringList funcs = " << DCOPParent << "::functions();" << endl;
|
||||
} else {
|
||||
str << " QCStringList funcs;" << endl;
|
||||
}
|
||||
str << " for ( int i = 0; " << className << "_ftable[i][2]; i++ ) {" << endl;
|
||||
str << "\tQCString func = " << className << "_ftable[i][0];" << endl;
|
||||
str << "\tfunc += ' ';" << endl;
|
||||
str << "\tfunc += " << className << "_ftable[i][2];" << endl;
|
||||
str << "\tfuncs << func;" << endl;
|
||||
str << " }" << endl;
|
||||
str << " return funcs;" << endl;
|
||||
str << "}" << endl << endl;
|
||||
}
|
||||
}
|
||||
|
||||
skel.close();
|
||||
}
|
@ -0,0 +1,312 @@
|
||||
/*****************************************************************
|
||||
Copyright (c) 1999 Torben Weis <weis@kde.org>
|
||||
Copyright (c) 2000 Matthias Ettrich <ettrich@kde.org>
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
|
||||
AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
******************************************************************/
|
||||
#include <qdom.h>
|
||||
#include <qfile.h>
|
||||
#include <qtextstream.h>
|
||||
#include <qstring.h>
|
||||
#include <qregexp.h>
|
||||
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include "main.h"
|
||||
|
||||
|
||||
QString javaType(QString type)
|
||||
{
|
||||
if (type == "bool")
|
||||
return "boolean";
|
||||
if (type == "QString")
|
||||
return "String";
|
||||
if (type == "QCString")
|
||||
return "String";
|
||||
if (type == "QStringList")
|
||||
return "String[]";
|
||||
if (type == "short int")
|
||||
return "short";
|
||||
if (type == "long int")
|
||||
return "int";
|
||||
|
||||
return type;
|
||||
}
|
||||
|
||||
|
||||
QString javaRightAttribute(QString attr)
|
||||
{
|
||||
if (attr == "&")
|
||||
return QString::null;
|
||||
|
||||
return "!!!NOT IMPLEMENTED: " + attr;
|
||||
}
|
||||
|
||||
|
||||
QString javaLeftAttribute(QString attr)
|
||||
{
|
||||
if (attr == "const")
|
||||
return QString::null;
|
||||
|
||||
return "!!!NOT IMPLEMENTED: " + attr;
|
||||
}
|
||||
|
||||
|
||||
QString javaQualifier(QString qual)
|
||||
{
|
||||
if (qual == "const")
|
||||
return QString::null;
|
||||
|
||||
return "!!!NOT IMPLEMENTED: " + qual;
|
||||
}
|
||||
|
||||
|
||||
QString underscore(QString in)
|
||||
{
|
||||
return in.replace(QRegExp(" "), "_");
|
||||
}
|
||||
|
||||
|
||||
QString defValue(QString type)
|
||||
{
|
||||
if (type == "bool")
|
||||
return "false";
|
||||
if (type == "QString")
|
||||
return "null";
|
||||
if (type == "QStringList")
|
||||
return "null";
|
||||
if (type == "DCOPRef")
|
||||
return "null";
|
||||
if (type == "QCString")
|
||||
return "null";
|
||||
|
||||
return "0";
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Writes the stub implementation
|
||||
*/
|
||||
void generateStubImpl( const QString& idl, const QString& package, const QString& filename, QDomElement de )
|
||||
{
|
||||
QFile impl( filename );
|
||||
if ( !impl.open( IO_WriteOnly ) )
|
||||
qFatal("Could not write to %s", filename.latin1() );
|
||||
|
||||
QTextStream str( &impl );
|
||||
|
||||
str << "/****************************************************************************" << endl;
|
||||
str << "**" << endl;
|
||||
str << "** DCOP Stub Implementation created by dcopidl2java from " << idl << endl;
|
||||
str << "**" << endl;
|
||||
str << "** WARNING! All changes made in this file will be lost!" << endl;
|
||||
str << "**" << endl;
|
||||
str << "*****************************************************************************/" << endl;
|
||||
str << endl;
|
||||
|
||||
if (!package.isEmpty())
|
||||
str << endl << "package " << package << ";" << endl << endl;
|
||||
|
||||
str << endl << "import java.io.*;" << endl;
|
||||
str << "import org.kde.DCOP.*;" << endl;
|
||||
str << endl << endl;
|
||||
|
||||
QDomElement e = de.firstChild().toElement();
|
||||
for( ; !e.isNull(); e = e.nextSibling().toElement() ) {
|
||||
if ( e.tagName() == "CLASS" ) {
|
||||
QDomElement n = e.firstChild().toElement();
|
||||
ASSERT( n.tagName() == "NAME" );
|
||||
QString className = n.firstChild().toText().data() + "_stub";
|
||||
|
||||
// find dcop parent ( rightmost super class )
|
||||
QString DCOPParent;
|
||||
QDomElement s = n.nextSibling().toElement();
|
||||
for( ; !s.isNull(); s = s.nextSibling().toElement() ) {
|
||||
if ( s.tagName() == "SUPER" )
|
||||
DCOPParent = s.firstChild().toText().data();
|
||||
}
|
||||
|
||||
// Start class definition
|
||||
str << "class " << className;
|
||||
|
||||
if ( DCOPParent.isEmpty() || DCOPParent == "DCOPObject" )
|
||||
str << " extends Stub" << endl;
|
||||
else
|
||||
str << " extends " << DCOPParent << endl;
|
||||
|
||||
str << "{" << endl;
|
||||
|
||||
// Write constructor
|
||||
str << " public " << className << "(String app, String obj)" << endl;
|
||||
str << " {" << endl << " super(app, obj);" << endl << " }" << endl;
|
||||
str << endl;
|
||||
|
||||
// Write marshalling code
|
||||
s = e.firstChild().toElement();
|
||||
for( ; !s.isNull(); s = s.nextSibling().toElement() ) {
|
||||
if ( s.tagName() == "FUNC" ) {
|
||||
QDomElement r = s.firstChild().toElement();
|
||||
ASSERT( r.tagName() == "TYPE" );
|
||||
QString result = r.firstChild().toText().data();
|
||||
str << " public ";
|
||||
bool async = result == "ASYNC";
|
||||
if ( async)
|
||||
result = "void";
|
||||
if ( r.hasAttribute( "qleft" ) )
|
||||
str << " " << javaLeftAttribute(r.attribute("qleft")) << " ";
|
||||
str << javaType(result);
|
||||
if ( r.hasAttribute( "qright" ) )
|
||||
str << " " << javaRightAttribute(r.attribute("qright")) << " ";
|
||||
else
|
||||
str << " ";
|
||||
|
||||
r = r.nextSibling().toElement();
|
||||
ASSERT ( r.tagName() == "NAME" );
|
||||
QString funcName = r.firstChild().toText().data();
|
||||
str << funcName << "(";
|
||||
|
||||
QStringList args;
|
||||
QStringList argtypes;
|
||||
bool first = TRUE;
|
||||
r = r.nextSibling().toElement();
|
||||
for( ; !r.isNull(); r = r.nextSibling().toElement() ) {
|
||||
if ( !first )
|
||||
str << ", ";
|
||||
first = FALSE;
|
||||
ASSERT( r.tagName() == "ARG" );
|
||||
QDomElement a = r.firstChild().toElement();
|
||||
ASSERT( a.tagName() == "TYPE" );
|
||||
if ( a.hasAttribute( "qleft" ) )
|
||||
str << javaLeftAttribute(a.attribute("qleft")) << " ";
|
||||
argtypes.append(a.firstChild().toText().data());
|
||||
str << javaType(argtypes.last());
|
||||
if ( a.hasAttribute( "qright" ) )
|
||||
str << javaRightAttribute(a.attribute("qright")) << " ";
|
||||
else
|
||||
str << " ";
|
||||
args.append(QString("arg") + QString::number(args.count())) ;
|
||||
str << args.last();
|
||||
}
|
||||
str << ")";
|
||||
|
||||
if ( s.hasAttribute("qual") )
|
||||
str << " " << javaQualifier(s.attribute("qual"));
|
||||
str << endl;
|
||||
|
||||
str << " {" << endl ;
|
||||
|
||||
funcName += "(";
|
||||
first = TRUE;
|
||||
for( QStringList::Iterator it = argtypes.begin(); it != argtypes.end(); ++it ){
|
||||
if ( !first )
|
||||
funcName += ",";
|
||||
first = FALSE;
|
||||
funcName += *it;
|
||||
}
|
||||
funcName += ")";
|
||||
|
||||
if ( async ) {
|
||||
str << " ByteArrayOutputStream bs = new ByteArrayOutputStream();" << endl;
|
||||
if ( !args.isEmpty() ) {
|
||||
str << " DataOutputStream os = new DataOutputStream(bs);" << endl;
|
||||
str << " try" << endl;
|
||||
str << " {" << endl;
|
||||
|
||||
QStringList::Iterator itt, ita;
|
||||
for (itt = argtypes.begin(), ita = args.begin(); itt != argtypes.end(); ++itt, ++ita)
|
||||
str << " write_" << *itt << "(os, " << *ita << ");" << endl;
|
||||
}
|
||||
str << " client().send(app(), obj(), \"" << funcName << "\", bs.toByteArray());" << endl;
|
||||
str << " setStatus(CallSucceeded);" << endl;
|
||||
if (!args.isEmpty())
|
||||
{
|
||||
str << " }" << endl;
|
||||
str << " catch (java.io.IOException e)" << endl;
|
||||
str << " {" << endl;
|
||||
str << " callFailed();" << endl;
|
||||
str << " }" << endl;
|
||||
}
|
||||
} else {
|
||||
|
||||
if ( result != "void" )
|
||||
str << " " << javaType(result) << " result = " << defValue(result) << ";" << endl;
|
||||
|
||||
str << " ByteArrayOutputStream data = new ByteArrayOutputStream();" << endl;
|
||||
|
||||
if ( !args.isEmpty() ) {
|
||||
str << " DataOutputStream os = new DataOutputStream(data);" << endl;
|
||||
str << " try" << endl;
|
||||
str << " {" << endl;
|
||||
|
||||
QStringList::Iterator itt, ita;
|
||||
for (itt = argtypes.begin(), ita = args.begin(); itt != argtypes.end(); ++itt, ++ita)
|
||||
str << " write_" << underscore(*itt) << "(os, " << *ita << ");" << endl;
|
||||
|
||||
}
|
||||
|
||||
str << " Response response = client().call(app(), obj(), \"" << funcName << "\", data.toByteArray(), false);" << endl;
|
||||
str << " if (response.returnValue)" << endl;
|
||||
str << " {" << endl;
|
||||
if ( result != "void" ) {
|
||||
str << " if (response.returnType.equals(\"" << result << "\"))" << endl;
|
||||
str << " {" << endl;
|
||||
str << " ByteArrayInputStream bi = new ByteArrayInputStream(response.returnData);" << endl;
|
||||
str << " DataInputStream is = new DataInputStream(bi);" << endl;
|
||||
str << " try" << endl;
|
||||
str << " {" << endl;
|
||||
str << " result = read_" << underscore(result) << "(is);" << endl;
|
||||
str << " setStatus( CallSucceeded );" << endl;
|
||||
str << " }" << endl;
|
||||
str << " catch (java.io.IOException e)" << endl;
|
||||
str << " {" << endl;
|
||||
str << " callFailed();" << endl;
|
||||
str << " }" << endl;
|
||||
str << " }" << endl;
|
||||
str << " else" << endl;
|
||||
str << " callFailed();" << endl;
|
||||
} else {
|
||||
str << " setStatus(CallSucceeded);" << endl;
|
||||
}
|
||||
str << " }" << endl;
|
||||
str << " else " << endl;
|
||||
str << " callFailed();" << endl;
|
||||
|
||||
|
||||
if (!args.isEmpty())
|
||||
{
|
||||
str << " }" << endl;
|
||||
str << " catch (java.io.IOException e)" << endl;
|
||||
str << " {" << endl;
|
||||
str << " callFailed();" << endl;
|
||||
str << " }" << endl;
|
||||
}
|
||||
|
||||
if ( result != "void" )
|
||||
str << " return result;" << endl;
|
||||
}
|
||||
str << " }" << endl << endl;
|
||||
}
|
||||
}
|
||||
str << "}" << endl;
|
||||
}
|
||||
}
|
||||
impl.close();
|
||||
}
|
@ -0,0 +1,17 @@
|
||||
INCLUDES = $(all_includes)
|
||||
|
||||
check_PROGRAMS = server test.class
|
||||
|
||||
server_SOURCES = main.cpp test.skel test_impl.cpp
|
||||
server_LDFLAGS = $(all_libraries)
|
||||
server_LDADD = $(LIB_KDECORE)
|
||||
|
||||
# test_class_SOURCES = test.java
|
||||
|
||||
test.class: test.java test_stub.java
|
||||
$(JAVAC) -classpath $(kde_libraries)/java:. test.java
|
||||
|
||||
test_stub.java: test.h test.kidl
|
||||
dcopidl2java test.kidl
|
||||
|
||||
CLEANFILES = test_stub.java test_stub.class
|
@ -0,0 +1,17 @@
|
||||
#include <kapplication.h>
|
||||
#include <dcopclient.h>
|
||||
|
||||
|
||||
#include "test_impl.h"
|
||||
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
KApplication app(argc, argv, "test-server", false, false);
|
||||
|
||||
app.dcopClient()->registerAs("test-server", false);
|
||||
|
||||
test_impl *t = new test_impl;
|
||||
|
||||
return app.exec();
|
||||
}
|
@ -0,0 +1,46 @@
|
||||
#ifndef _TEST_H_
|
||||
#define _TEST_H_
|
||||
|
||||
|
||||
#include <qstring.h>
|
||||
#include <qstringlist.h>
|
||||
|
||||
|
||||
#include <dcopobject.h>
|
||||
#include <dcopref.h>
|
||||
|
||||
|
||||
class test : virtual public DCOPObject
|
||||
{
|
||||
K_DCOP
|
||||
|
||||
public:
|
||||
|
||||
k_dcop:
|
||||
|
||||
virtual void noArg() = 0;
|
||||
virtual ASYNC asyncNoArg() = 0;
|
||||
|
||||
virtual void oneArg(bool val) = 0;
|
||||
virtual bool returnFalse() = 0;
|
||||
virtual bool returnTrue() = 0;
|
||||
|
||||
virtual short shortArg(short in) = 0;
|
||||
virtual int intArg(int in) = 0;
|
||||
virtual long longArg(long in) = 0;
|
||||
|
||||
virtual float floatArg(float in) = 0;
|
||||
virtual double doubleArg(double in) = 0;
|
||||
|
||||
virtual QString stringArg(QString in) = 0;
|
||||
virtual QStringList stringListArg(QStringList in) = 0;
|
||||
|
||||
virtual QCString cstringArg(QCString in) = 0;
|
||||
|
||||
virtual DCOPRef DCOPRefArg(DCOPRef in) = 0;
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
#endif
|
@ -0,0 +1,78 @@
|
||||
import org.kde.DCOP.*;
|
||||
|
||||
|
||||
class test
|
||||
{
|
||||
|
||||
public static void main(String[] argv)
|
||||
{
|
||||
test_stub test = new test_stub("test-server", "test");
|
||||
|
||||
System.out.println("Calling server without args:");
|
||||
test.noArg();
|
||||
System.out.println("");
|
||||
|
||||
System.out.println("Calling server asynchronously without args:");
|
||||
test.asyncNoArg();
|
||||
System.out.println("");
|
||||
|
||||
System.out.println("Calling server with one argument: bool=true:");
|
||||
test.oneArg(true);
|
||||
System.out.println("");
|
||||
|
||||
System.out.println("Calling server with one argument: bool=false:");
|
||||
test.oneArg(false);
|
||||
System.out.println("");
|
||||
|
||||
System.out.println("Calling server: returnFalse");
|
||||
boolean ret = test.returnFalse();
|
||||
System.out.print("Returned: ");
|
||||
if (ret)
|
||||
System.out.println("True");
|
||||
else
|
||||
System.out.println("False");
|
||||
System.out.println();
|
||||
|
||||
System.out.println("Calling server: returnTrue");
|
||||
ret = test.returnTrue();
|
||||
System.out.print("Returned: ");
|
||||
if (ret)
|
||||
System.out.println("True");
|
||||
else
|
||||
System.out.println("False");
|
||||
System.out.println();
|
||||
|
||||
System.out.println("Calling server: short");
|
||||
System.out.println(test.shortArg((short)(51)));
|
||||
|
||||
System.out.println("Calling server: int");
|
||||
System.out.println(test.intArg(512));
|
||||
|
||||
System.out.println("Calling server: long");
|
||||
System.out.println(test.longArg(999999));
|
||||
|
||||
System.out.println("Calling server: float");
|
||||
System.out.println(test.floatArg(5.1212f));
|
||||
|
||||
System.out.println("Calling server: double");
|
||||
System.out.println(test.doubleArg(0.001122));
|
||||
|
||||
System.out.println("Calling server: String");
|
||||
System.out.println(test.stringArg("Hallo Server"));
|
||||
|
||||
String[] in = { "alpha", "beta", "gamma", "delta" };
|
||||
System.out.println("Calling server: String[]");
|
||||
String[] out = test.stringListArg(in);
|
||||
for (int i=0; i<out.length; ++i)
|
||||
System.out.println(out[i]);
|
||||
|
||||
System.out.println("Calling server: CString");
|
||||
System.out.println(test.cstringArg("Hallo Server"));
|
||||
|
||||
DCOPRef rin = new DCOPRef("app", "obj", "typ");
|
||||
System.out.println("Calling server: DCOPRef");
|
||||
DCOPRef rout = test.DCOPRefArg(rin);
|
||||
System.out.println("Reference: " + rout.app() + ", " +
|
||||
rout.object() + ", " + rout.type());
|
||||
}
|
||||
}
|
@ -0,0 +1,108 @@
|
||||
#include <stream.h>
|
||||
#include <stdio.h>
|
||||
|
||||
|
||||
#include "test_impl.h"
|
||||
|
||||
|
||||
void test_impl::noArg()
|
||||
{
|
||||
printf("SERVER: noArg() called\n");
|
||||
}
|
||||
|
||||
|
||||
void test_impl::asyncNoArg()
|
||||
{
|
||||
printf("SERVER: asyncNoArg() called\n");
|
||||
}
|
||||
|
||||
|
||||
void test_impl::oneArg(bool b)
|
||||
{
|
||||
printf("SERVER: oneArg(");
|
||||
printf(b ? "true" : "false");
|
||||
printf(") called\n");
|
||||
}
|
||||
|
||||
|
||||
bool test_impl::returnFalse()
|
||||
{
|
||||
printf("SERVER: returnFalse() called\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
bool test_impl::returnTrue()
|
||||
{
|
||||
printf("SERVER: returnTrue() called\n");
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
short test_impl::shortArg(short in)
|
||||
{
|
||||
cout << "SERVER: short in: " << in << endl;
|
||||
return 123;
|
||||
}
|
||||
|
||||
|
||||
int test_impl::intArg(int in)
|
||||
{
|
||||
cout << "SERVER: int in: " << in << endl;
|
||||
return 123456;
|
||||
}
|
||||
|
||||
|
||||
long test_impl::longArg(long in)
|
||||
{
|
||||
cout << "SERVER: long in: " << in << endl;
|
||||
return 1234567890;
|
||||
}
|
||||
|
||||
|
||||
float test_impl::floatArg(float in)
|
||||
{
|
||||
cout << "SERVER: float in: " << in << endl;
|
||||
return 12.34;
|
||||
}
|
||||
|
||||
|
||||
double test_impl::doubleArg(double in)
|
||||
{
|
||||
cout << "SERVER: double in: " << in << endl;
|
||||
return 12.12313123;
|
||||
}
|
||||
|
||||
|
||||
QString test_impl::stringArg(QString in)
|
||||
{
|
||||
cout << "SERVER: QString in: " << in << endl;
|
||||
return "Hello Java";
|
||||
}
|
||||
|
||||
|
||||
QCString test_impl::cstringArg(QCString in)
|
||||
{
|
||||
cout << "SERVER: QCString in: " << in << endl;
|
||||
return "Hello Java";
|
||||
}
|
||||
|
||||
|
||||
QStringList test_impl::stringListArg(QStringList in)
|
||||
{
|
||||
cout << "SERVER: QStringList in: ";
|
||||
for (uint i=0; i<in.count(); ++i)
|
||||
cout << in[i] << ", ";
|
||||
cout << endl;
|
||||
QStringList result;
|
||||
result << "one" << "two" << "three";
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
DCOPRef test_impl::DCOPRefArg(DCOPRef in)
|
||||
{
|
||||
cout << "SERVER: DCOPRef in: " << in.app() << ", "
|
||||
<< in.object() << ", " << in.type() << endl;
|
||||
return DCOPRef("application", "object", "type");
|
||||
}
|
@ -0,0 +1,38 @@
|
||||
#include "test.h"
|
||||
|
||||
|
||||
class test_impl : virtual public test
|
||||
{
|
||||
public:
|
||||
|
||||
test_impl() : DCOPObject("test") {};
|
||||
|
||||
void noArg();
|
||||
|
||||
void asyncNoArg();
|
||||
|
||||
void oneArg(bool b);
|
||||
|
||||
bool returnFalse();
|
||||
|
||||
bool returnTrue();
|
||||
|
||||
short shortArg(short in);
|
||||
|
||||
int intArg(int in);
|
||||
|
||||
long longArg(long in);
|
||||
|
||||
float floatArg(float in);
|
||||
|
||||
double doubleArg(double in);
|
||||
|
||||
QString stringArg(QString in);
|
||||
|
||||
QCString cstringArg(QCString in);
|
||||
|
||||
QStringList stringListArg(QStringList in);
|
||||
|
||||
DCOPRef DCOPRefArg(DCOPRef in);
|
||||
|
||||
};
|
@ -0,0 +1 @@
|
||||
Malte Starostik <malte@kde.org>
|
@ -0,0 +1,5 @@
|
||||
Revision history for Perl extension DCOP.
|
||||
|
||||
0.01 Thu Aug 24 15:46:42 2000
|
||||
- original version; created by h2xs 1.19
|
||||
|
@ -0,0 +1,303 @@
|
||||
package DCOP;
|
||||
|
||||
use strict;
|
||||
use vars qw($VERSION @ISA);
|
||||
|
||||
use DynaLoader;
|
||||
use DCOP::Object;
|
||||
|
||||
@ISA = qw(DynaLoader);
|
||||
|
||||
$VERSION = '0.01';
|
||||
|
||||
bootstrap DCOP $VERSION;
|
||||
|
||||
# Returns a DCOP::Object that is logically bound to a specific object of a specific app
|
||||
sub createObject
|
||||
{
|
||||
my ($self, $app, $obj) = @_;
|
||||
$obj = "default" unless defined $obj;
|
||||
$self = {
|
||||
CLIENT => $self,
|
||||
APP => $app,
|
||||
OBJ => $obj,
|
||||
};
|
||||
bless $self, "DCOP::Object";
|
||||
}
|
||||
|
||||
# That's it :)
|
||||
|
||||
1;
|
||||
__END__
|
||||
|
||||
=head1 NAME
|
||||
|
||||
DCOP - Perl extension for communcation with KDE's DCOP server
|
||||
|
||||
=head1 SYNOPSIS
|
||||
|
||||
use DCOP;
|
||||
|
||||
my $client = new DCOP;
|
||||
$client->attach();
|
||||
$running_apps = $client->registeredApplications();
|
||||
$client->send("kmail", "KMailIface", "checkMail()");
|
||||
|
||||
my $kmail = $client->createObject("kmail", "KMailIface");
|
||||
$kmail->openComposer("fred@outer.space",
|
||||
undef,
|
||||
undef,
|
||||
"This is a mail initiated by DCOP.pm",
|
||||
0,
|
||||
"file:/home/joe/file/with/mail/to/send");
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
The Desktop COmmunication Protocol is used by almost every KDE application
|
||||
and is a lightweight but powerful IPC mechanism. For more information look at
|
||||
|
||||
http://developer.kde.org/documentation/library/2.0-api/dcop/HOWTO.html
|
||||
|
||||
This Perl extension can be used to send commands to any currently registered
|
||||
DCOP application, as well as query which apps are registered and what
|
||||
interfaces with what functions they offer. Additionally you can use DCOP::Object
|
||||
to trigger DCOP sends or calls as native methods of DCOP::Object
|
||||
(see the secion on Autoload Magic below).
|
||||
|
||||
=head2 Creation, Attachment and Registration
|
||||
|
||||
Creating a DCOP client is as simple as it gets:
|
||||
|
||||
use DCOP;
|
||||
|
||||
$client = new DCOP;
|
||||
|
||||
That's it. Some arguments to new are planned for future releases.
|
||||
After creation the client is not attached to the server. The easiest way to
|
||||
establish a connection is
|
||||
|
||||
$client->attach();
|
||||
|
||||
which registers your DCOP client anonymously.
|
||||
To register with a well known name use:
|
||||
|
||||
$client->registerAs("fred");
|
||||
NOTE: registerAs is currently disabled
|
||||
|
||||
To close the connection, simply call
|
||||
|
||||
$client->detach();
|
||||
|
||||
=head2 Hello World!
|
||||
|
||||
Now that you have your client registered with the server, either anonymously
|
||||
or by name, you can use it to query information about other registered applications.
|
||||
To get a list with names of all clients, use:
|
||||
|
||||
$client->registeredApplications();
|
||||
|
||||
To retrieve the Qt object hierarchy of an application, call
|
||||
|
||||
$client->remoteObjects($appname);
|
||||
|
||||
Similarly you can get a list of supported interfaces with
|
||||
|
||||
$client->remoteIterfaces($appname, $objectname);
|
||||
|
||||
And to know what you can do with all these nice interfaces, learn about their functions:
|
||||
|
||||
$client->remoteFunctions($appname, $objectname);
|
||||
|
||||
=head2 Let them do something
|
||||
|
||||
To simply dispatch a command neglecting its return value, use
|
||||
|
||||
$client->send($appname, $objectname, $function, ...);
|
||||
|
||||
If you're interested in the return value, consider call:
|
||||
|
||||
$client->call($appname, $objectname, $function, ...);
|
||||
|
||||
=head2 Autoload Magic
|
||||
|
||||
A much more intuitive way to use send and call is via DCOP::Object. This class
|
||||
is not intended for explicit instantiation and is merely a very small autoload stub.
|
||||
To get a DCOP::Object, simply call
|
||||
|
||||
$obj = $client->createObject($appname [, $objectname]);
|
||||
|
||||
The returned $obj is a DCOP::Object "bound" to the specified application and object
|
||||
(or the app's default object if $objectname is omitted or undef). This DCOP::Object
|
||||
has only two known methods, _app() and _object() which return the application and object
|
||||
name respectively and are merely for internal use. Any other method you call will be
|
||||
looked up in the functions() list of the target object. So, if you created it e.g. with
|
||||
|
||||
$obj = $client->createObject("kmail", "KMailIface");
|
||||
|
||||
You can simply invoke
|
||||
|
||||
$obj->checkMail();
|
||||
|
||||
instead of
|
||||
|
||||
$client->send("kmail", "KMailIface", "checkMail()");
|
||||
|
||||
=head2 Detailed Reference
|
||||
|
||||
sub new(); [ class method ]
|
||||
|
||||
takes no arguments by now and returns a blessed reference to a new DCOP client.
|
||||
|
||||
sub attach();
|
||||
|
||||
returns a true value if the attachment succeeded or undef on error.
|
||||
|
||||
sub detach();
|
||||
|
||||
returns a true value if the client was successfully detached or undef on error.
|
||||
|
||||
sub isAttached();
|
||||
|
||||
returns true or undef whether the client is attached or not.
|
||||
|
||||
sub registerAs($appId [, $addPID]);
|
||||
CURRENTLY DISABLED
|
||||
|
||||
registers the client with the name $appId or $appId with a number appended if a
|
||||
client by that name already exists. If $addPID is true, the PID of the client is
|
||||
appended to the appId, seperated by a hyphen. If addPID is ommited, it defaults to
|
||||
true. To not add a PID, specify undef or zero.
|
||||
registerAs returns the actual appId after the PID or possibly a sequence number has
|
||||
been added.
|
||||
If you call this method on an already attached or registered client, the old appId will
|
||||
be replaced with the new one.
|
||||
|
||||
sub isRegistered();
|
||||
CURRENTLY DISABLED
|
||||
|
||||
like isAttached but returns true only if the client used registerAs.
|
||||
|
||||
sub appId();
|
||||
|
||||
returns the appId the client is known as or undef if it's not registered or only
|
||||
attached anonymously.
|
||||
|
||||
sub send($app, $object, $function [, ...])
|
||||
|
||||
dispatches a function call without waiting for completion and thus without retrieving
|
||||
a return value. Returns true if a matching object has been found or undef otherwise.
|
||||
$app is the name of a registered application,
|
||||
$object the name of an object implemented by $app or undef for the default object,
|
||||
$function is the signature of the function to be called.
|
||||
Any following arguments are passed as parameters to the called function.
|
||||
Make sure that they match the function's signature in count and types (see Datatypes below)
|
||||
or your program will die. (This will be configurable in later versions)
|
||||
|
||||
sub call($app, $object, $function [, ...])
|
||||
|
||||
like send, but blocks until the called function returns and supplies the return value of that
|
||||
function (see Datatypes below). In scalar context, the value returned is the function's return
|
||||
value, in list context call returns a two element list with the first item set to the function's
|
||||
repturn value and the second set to true or undef according to success or failure of the DCOP call.
|
||||
|
||||
|
||||
sub findObject
|
||||
|
||||
not really implemented, yet.
|
||||
|
||||
sub emitDCOPSignal
|
||||
|
||||
dito.
|
||||
|
||||
sub isApplicationRegistered($app)
|
||||
|
||||
returns true if an application with the given name is known to the DCOP server or otherwise undef.
|
||||
|
||||
sub registeredApplications()
|
||||
|
||||
returns a reference to an array with the names of all currently registered applications.
|
||||
On error it returns undef.
|
||||
|
||||
sub remoteObjects($app)
|
||||
|
||||
returns a reference to an array with the names of the objects supported by the named application.
|
||||
On error it returns undef.
|
||||
|
||||
sub remoteInterfaces($app, $object)
|
||||
|
||||
returns a reference to an array with the names of the interfaces supported by the given application
|
||||
and object. On error it returns undef.
|
||||
|
||||
sub remoteFunctions($app, $object)
|
||||
|
||||
returns a reference to an array with the names of the functions the specified interface supports.
|
||||
The functions are returned as their signatures with parameter names and return type like
|
||||
|
||||
QCStringList functions()
|
||||
|
||||
sub normalizeSignature($signature)
|
||||
|
||||
removes extraneous whitespace from a function signature.
|
||||
|
||||
sub canonicalizeSignature($signature)
|
||||
|
||||
mostly for internal use. Calls normalizeSignature and then strips parameter names and
|
||||
return type from it.
|
||||
|
||||
=head2 Datatypes
|
||||
|
||||
The following datatypes are currently supported in arguments to send and call and as
|
||||
return values:
|
||||
|
||||
=over 4
|
||||
|
||||
=item * int
|
||||
mapped to scalar
|
||||
|
||||
=item * QCString
|
||||
mapped to scalar
|
||||
|
||||
=item * QString (no Unicode support yet, just latin 1)
|
||||
mapped to scalar
|
||||
|
||||
=item * QCStringList
|
||||
mapped to a reference to an array of scalars.
|
||||
|
||||
=item * QStringList
|
||||
mapped to a reference to an array of scalars.
|
||||
|
||||
=item * QPoint (untested)
|
||||
mapped to a reference to a two elemtent array [$x, $y]
|
||||
named value support via hash planned.
|
||||
|
||||
=item * QSize (untested)
|
||||
mapped to a reference to a two elemtent array [$width, $height]
|
||||
named value support via hash planned.
|
||||
|
||||
=item * QRect (untested)
|
||||
mapped to a reference to a four elemtent array [$left, $top, $width, $height]
|
||||
named value support via hash planned (including alternative right and bottom / width height)
|
||||
|
||||
=item * KURL (only QString url() now)
|
||||
mapped to scalar
|
||||
|
||||
=item * DCOPRef (partially)
|
||||
mapped to DCOP::Object, methods like isNull() missing.
|
||||
|
||||
=back
|
||||
|
||||
=head1 BUGS
|
||||
Most probably many. A lot of memory leaks I fear, but that has to be proven.
|
||||
There are many important features missing also. By now, it is not possible to
|
||||
use DCOP.pm to receive DCOP messages. That is planned.
|
||||
|
||||
=head1 AUTHOR
|
||||
|
||||
Malte Starostik, malte@kde.org
|
||||
|
||||
=head1 SEE ALSO
|
||||
|
||||
perl(1).
|
||||
|
||||
=cut
|
||||
|
@ -0,0 +1,492 @@
|
||||
|
||||
#include "EXTERN.h"
|
||||
#include "perl.h"
|
||||
#include "XSUB.h"
|
||||
|
||||
#ifdef METHOD
|
||||
#undef METHOD
|
||||
#endif
|
||||
|
||||
#ifdef ref
|
||||
#undef ref
|
||||
#endif
|
||||
#ifdef list
|
||||
#undef list
|
||||
#endif
|
||||
#ifdef do_open
|
||||
#undef do_open
|
||||
#endif
|
||||
#ifdef do_close
|
||||
#undef do_close
|
||||
#endif
|
||||
#ifdef assert
|
||||
#undef assert
|
||||
#endif
|
||||
#ifdef vform
|
||||
#undef vform
|
||||
#endif
|
||||
|
||||
#include <qpoint.h>
|
||||
#include <qrect.h>
|
||||
#include <qregexp.h>
|
||||
#include <qsize.h>
|
||||
#include <qstringlist.h>
|
||||
|
||||
#include <dcopclient.h>
|
||||
#include <dcopref.h>
|
||||
#include <kdatastream.h>
|
||||
#include <kurl.h>
|
||||
|
||||
int intFromSV(SV *data)
|
||||
{
|
||||
if (!SvOK(data))
|
||||
return 0;
|
||||
if (!SvIOK(data))
|
||||
croak("DCOP: Cannot convert to integer");
|
||||
return SvIV(data);
|
||||
}
|
||||
|
||||
SV *intToSV(int data, SV * self = 0)
|
||||
{
|
||||
return newSViv(data);
|
||||
}
|
||||
|
||||
uint uintFromSV(SV *data)
|
||||
{
|
||||
if (!SvOK(data))
|
||||
return 0;
|
||||
if (!SvIOK(data))
|
||||
croak("DCOP: Cannot convert to integer");
|
||||
return SvIV(data);
|
||||
}
|
||||
|
||||
SV *uintToSV(uint data, SV * self = 0)
|
||||
{
|
||||
return newSViv(data);
|
||||
}
|
||||
|
||||
|
||||
bool boolFromSV(SV *data)
|
||||
{
|
||||
if (!SvOK(data))
|
||||
return false;
|
||||
if (SvIOK(data))
|
||||
return SvIV(data);
|
||||
if (SvPOK(data))
|
||||
return QCString(SvPV(data, PL_na)).lower() == "true";
|
||||
croak("DCOP: Cannot convert to bool");
|
||||
}
|
||||
|
||||
SV *boolToSV(bool data, SV *self = 0)
|
||||
{
|
||||
return newSViv(data ? 1 : 0);
|
||||
}
|
||||
|
||||
QCString QCStringFromSV(SV *data)
|
||||
{
|
||||
if (!SvOK(data))
|
||||
return QCString();
|
||||
if (!SvPOK(data))
|
||||
croak("DCOP: Cannot convert to QCString");
|
||||
return SvPV(data, PL_na);
|
||||
}
|
||||
|
||||
SV *QCStringToSV(const QCString &data, SV * self = 0)
|
||||
{
|
||||
return data.isNull() ? &PL_sv_undef : newSVpv(data.data(), 0);
|
||||
}
|
||||
|
||||
QString QStringFromSV(SV *data)
|
||||
{
|
||||
if (!SvOK(data))
|
||||
return QString::null;
|
||||
if (!SvPOK(data))
|
||||
croak("DCOP: Cannot convert to QString");
|
||||
return SvPV(data, PL_na);
|
||||
}
|
||||
|
||||
SV *QStringToSV(const QString &data, SV * self = 0)
|
||||
{
|
||||
return data.isNull() ? &PL_sv_undef : newSVpv((char *)data.latin1(), 0);
|
||||
}
|
||||
|
||||
QCStringList QCStringListFromSV(SV *data)
|
||||
{
|
||||
if (!SvROK(data))
|
||||
croak("DCOP: Not reference");
|
||||
if (SvTYPE(SvRV(data)) != SVt_PVAV)
|
||||
croak("DCOP: Not an array reference");
|
||||
QCStringList result;
|
||||
for (int i = 0; i <= av_len((AV*)SvRV(data)); i++)
|
||||
result.append(QCStringFromSV(av_fetch((AV*)SvRV(data), i, 0)[0]));
|
||||
return result;
|
||||
}
|
||||
|
||||
SV *QCStringListToSV(const QCStringList &data, SV * self = 0)
|
||||
{
|
||||
AV *result = newAV();
|
||||
for (QCStringList::ConstIterator i = data.begin(); i != data.end(); i++)
|
||||
av_push(result, QCStringToSV(*i));
|
||||
return newRV((SV*)result);
|
||||
}
|
||||
|
||||
QStringList QStringListFromSV(SV *data)
|
||||
{
|
||||
if (!SvROK(data))
|
||||
croak("DCOP: Not reference");
|
||||
if (SvTYPE(SvRV(data)) != SVt_PVAV)
|
||||
croak("DCOP: Not an array reference");
|
||||
QStringList result;
|
||||
for (int i = 0; i <= av_len((AV*)SvRV(data)); i++)
|
||||
result.append(QCStringFromSV(av_fetch((AV*)SvRV(data), i, 0)[0]));
|
||||
return result;
|
||||
}
|
||||
|
||||
SV *QStringListToSV(const QStringList &data, SV * self = 0)
|
||||
{
|
||||
AV *result = newAV();
|
||||
for (QStringList::ConstIterator i = data.begin(); i != data.end(); i++)
|
||||
av_push(result, QStringToSV(*i));
|
||||
return newRV((SV*)result);
|
||||
}
|
||||
|
||||
QPoint QPointFromSV(SV *data)
|
||||
{
|
||||
if (!SvROK(data))
|
||||
croak("DCOP: Not reference");
|
||||
if (SvTYPE(SvRV(data)) != SVt_PVAV)
|
||||
croak("DCOP: Not an array reference");
|
||||
if (av_len((AV*)SvRV(data)) != 1)
|
||||
croak("DCOP: A QPoint must have exactly 2 components");
|
||||
SV **pts = av_fetch((AV*)SvRV(data), 0, 0);
|
||||
return QPoint(intFromSV(pts[0]), intFromSV(pts[1]));
|
||||
}
|
||||
|
||||
SV *QPointToSV(const QPoint &data, SV * self = 0)
|
||||
{
|
||||
SV *pts[2] = {
|
||||
intToSV(data.x()),
|
||||
intToSV(data.y())
|
||||
};
|
||||
return newRV((SV*)av_make(2, pts));
|
||||
}
|
||||
|
||||
QSize QSizeFromSV(SV *data)
|
||||
{
|
||||
if (!SvROK(data))
|
||||
croak("DCOP: Not reference");
|
||||
if (SvTYPE(SvRV(data)) != SVt_PVAV)
|
||||
croak("DCOP: Not an array reference");
|
||||
if (av_len((AV*)SvRV(data)) != 1)
|
||||
croak("DCOP: A QSize must have exactly 2 components");
|
||||
SV **ext = av_fetch((AV*)SvRV(data), 0, 0);
|
||||
return QSize(intFromSV(ext[0]), intFromSV(ext[1]));
|
||||
}
|
||||
|
||||
SV *QSizeToSV(const QSize &data, SV * self = 0)
|
||||
{
|
||||
SV *ext[2] = {
|
||||
intToSV(data.width()),
|
||||
intToSV(data.height())
|
||||
};
|
||||
return newRV((SV*)av_make(2, ext));
|
||||
}
|
||||
|
||||
QRect QRectFromSV(SV *data)
|
||||
{
|
||||
if (!SvROK(data))
|
||||
croak("DCOP: Not a reference");
|
||||
if (SvTYPE(SvRV(data)) != SVt_PVAV)
|
||||
croak("DCOP: Not an array reference");
|
||||
if (av_len((AV*)SvRV(data)) != 1)
|
||||
croak("DCOP: A QRect must have exactly 4 components");
|
||||
SV **rc = av_fetch((AV*)SvRV(data), 0, 0);
|
||||
return QRect(intFromSV(rc[0]), intFromSV(rc[1]), intFromSV(rc[2]), intFromSV(rc[3]));
|
||||
}
|
||||
|
||||
SV *QRectToSV(const QRect &data, SV * self = 0)
|
||||
{
|
||||
SV *rc[4] = {
|
||||
intToSV(data.left()),
|
||||
intToSV(data.top()),
|
||||
intToSV(data.width()),
|
||||
intToSV(data.height())
|
||||
};
|
||||
return newRV((SV*)av_make(4, rc));
|
||||
}
|
||||
|
||||
KURL KURLFromSV(SV *data)
|
||||
{
|
||||
return KURL(QStringFromSV(data));
|
||||
}
|
||||
|
||||
SV *KURLToSV(const KURL &data, SV * self = 0)
|
||||
{
|
||||
return QStringToSV(data.url());
|
||||
}
|
||||
|
||||
DCOPRef DCOPRefFromSV(SV *data)
|
||||
{
|
||||
if (!sv_isa(data, "DCOP::Object"))
|
||||
croak("DCOP: Not a DCOP::Object");
|
||||
SV **app = hv_fetch((HV*)SvRV(data), "APP", 3, 0);
|
||||
SV **obj = hv_fetch((HV*)SvRV(data), "OBJ", 3, 0);
|
||||
return DCOPRef(QCStringFromSV(app[0]), QCStringFromSV(obj[0]));
|
||||
}
|
||||
|
||||
SV *DCOPRefToSV(const DCOPRef &data, SV * self)
|
||||
{
|
||||
SV *ref = newRV((SV*)newHV());
|
||||
hv_store((HV*)SvRV(ref), "CLIENT", 6, SvREFCNT_inc(self), 0);
|
||||
hv_store((HV*)SvRV(ref), "APP", 3, QCStringToSV(data.app()), 0);
|
||||
hv_store((HV*)SvRV(ref), "OBJ", 3, QCStringToSV(data.object()), 0);
|
||||
return sv_bless(ref, gv_stashpv("DCOP::Object", 0));
|
||||
}
|
||||
|
||||
# // Yes, defines *are* ugly...
|
||||
#define CHECK_ARG(t) \
|
||||
if ((*it) == #t) \
|
||||
s << t##FromSV(data[i]);
|
||||
|
||||
#define CHECK_REPLY(t) \
|
||||
if (replyType == #t) \
|
||||
{ \
|
||||
t r; \
|
||||
s >> r; \
|
||||
return t##ToSV(r, self); \
|
||||
}
|
||||
|
||||
#define DATA(func, argn) mapArgs(func, &ST(argn), items - argn)
|
||||
|
||||
QByteArray mapArgs(const QCString &func, SV **data, int n)
|
||||
{
|
||||
int p = func.find('('),
|
||||
q = func.find(')');
|
||||
if (p == -1 || q == -1 || q < p)
|
||||
croak("DCOP: Invalid function signature \"%s\"", func.data());
|
||||
QStringList types = QStringList::split(',', func.mid(p + 1, q - p - 1));
|
||||
QByteArray result;
|
||||
QDataStream s(result, IO_WriteOnly);
|
||||
QStringList::ConstIterator it = types.begin();
|
||||
for (int i = 0; i < n; ++i, ++it)
|
||||
{
|
||||
if (it == types.end())
|
||||
croak("DCOP: Too many (%d) arguments to function \"%s\"", n, func.data());
|
||||
CHECK_ARG(int)
|
||||
else CHECK_ARG(uint)
|
||||
else CHECK_ARG(bool)
|
||||
else CHECK_ARG(QCString)
|
||||
else CHECK_ARG(QString)
|
||||
else CHECK_ARG(QCStringList)
|
||||
else CHECK_ARG(QStringList)
|
||||
else CHECK_ARG(QPoint)
|
||||
else CHECK_ARG(QSize)
|
||||
else CHECK_ARG(QRect)
|
||||
else CHECK_ARG(KURL)
|
||||
else CHECK_ARG(DCOPRef)
|
||||
else
|
||||
croak("DCOP: Sorry, passing a %s is not implemented", (*it).latin1());
|
||||
}
|
||||
if (it != types.end())
|
||||
croak("DCOP: Too few (%d) arguments to function \"%s\"", n, func.data());
|
||||
return result;
|
||||
}
|
||||
|
||||
SV* mapReply(const QCString &replyType, const QByteArray &replyData, SV *self)
|
||||
{
|
||||
if (replyType == "void")
|
||||
return sv_newmortal();
|
||||
QDataStream s(replyData, IO_ReadOnly);
|
||||
CHECK_REPLY(int)
|
||||
else CHECK_REPLY(uint)
|
||||
else CHECK_REPLY(bool)
|
||||
else CHECK_REPLY(QCString)
|
||||
else CHECK_REPLY(QString)
|
||||
else CHECK_REPLY(QCStringList)
|
||||
else CHECK_REPLY(QStringList)
|
||||
else CHECK_REPLY(QPoint)
|
||||
else CHECK_REPLY(QSize)
|
||||
else CHECK_REPLY(QRect)
|
||||
else CHECK_REPLY(KURL)
|
||||
else CHECK_REPLY(DCOPRef)
|
||||
else croak("Sorry, receiving a %s is not implemented", replyType.data());
|
||||
}
|
||||
|
||||
bool isMultiWordType(const QString &type)
|
||||
{
|
||||
return type == "unsigned" || type == "signed" || type == "long";
|
||||
}
|
||||
|
||||
QCString canonicalizeSignature(const QCString &sig)
|
||||
{
|
||||
QCString normal = DCOPClient::normalizeFunctionSignature(sig);
|
||||
int p = normal.find('('), q = normal.find(')');
|
||||
QCString result = normal.left(p + 1);
|
||||
result.remove(0, result.findRev(' ') + 1);
|
||||
|
||||
QStringList params = QStringList::split(',', normal.mid(p + 1, q - p - 1));
|
||||
for (QStringList::ConstIterator it = params.begin(); it != params.end(); ++it)
|
||||
{
|
||||
QStringList words = QStringList::split(' ', (*it).simplifyWhiteSpace());
|
||||
for (QStringList::ConstIterator wi = words.begin(); wi != words.end(); ++wi)
|
||||
if (!isMultiWordType(*wi))
|
||||
{
|
||||
result += *wi;
|
||||
break;
|
||||
}
|
||||
if (it != params.fromLast())
|
||||
result += ',';
|
||||
}
|
||||
result += ')';
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
MODULE = DCOP PACKAGE = DCOP
|
||||
|
||||
PROTOTYPES: ENABLE
|
||||
|
||||
DCOPClient *
|
||||
DCOPClient::new()
|
||||
OUTPUT:
|
||||
RETVAL
|
||||
|
||||
void
|
||||
DCOPClient::DESTROY()
|
||||
|
||||
bool
|
||||
DCOPClient::attach()
|
||||
OUTPUT:
|
||||
RETVAL
|
||||
|
||||
bool
|
||||
DCOPClient::detach()
|
||||
OUTPUT:
|
||||
RETVAL
|
||||
|
||||
bool
|
||||
DCOPClient::isAttached()
|
||||
OUTPUT:
|
||||
RETVAL
|
||||
|
||||
#if 0
|
||||
QCString
|
||||
DCOPClient::registerAs(appId, ...)
|
||||
QCString appId
|
||||
PREINIT:
|
||||
bool addPID = true;
|
||||
CODE:
|
||||
if (items > 3)
|
||||
croak("Usage: DCOP::registerAs(THIS, appId [, addPID])");
|
||||
if (items == 3)
|
||||
addPID = SvIV(ST(2));
|
||||
RETVAL = THIS->registerAs(appId, addPID);
|
||||
OUTPUT:
|
||||
RETVAL
|
||||
|
||||
bool
|
||||
DCOPClient::isRegistered()
|
||||
OUTPUT:
|
||||
RETVAL
|
||||
|
||||
#endif
|
||||
|
||||
QCString
|
||||
DCOPClient::appId()
|
||||
OUTPUT:
|
||||
RETVAL
|
||||
|
||||
bool
|
||||
DCOPClient::send(app, obj, func, ...)
|
||||
QCString app
|
||||
QCString obj
|
||||
QCString func
|
||||
CODE:
|
||||
func = canonicalizeSignature(func);
|
||||
RETVAL = THIS->send(app, obj, func, DATA(func, 4));
|
||||
OUTPUT:
|
||||
RETVAL
|
||||
|
||||
SV*
|
||||
DCOPClient::call(app, obj, func, ...)
|
||||
QCString app
|
||||
QCString obj
|
||||
QCString func
|
||||
PPCODE:
|
||||
func = canonicalizeSignature(func);
|
||||
QCString replyType;
|
||||
QByteArray replyData;
|
||||
bool success;
|
||||
if ((success = THIS->call(app, obj, func, DATA(func, 4), replyType, replyData)))
|
||||
PUSHs(mapReply(replyType, replyData, ST(0)));
|
||||
else
|
||||
PUSHs(&PL_sv_undef);
|
||||
if (GIMME_V == G_ARRAY)
|
||||
PUSHs(success ? &PL_sv_yes : &PL_sv_no);
|
||||
|
||||
SV*
|
||||
DCOPClient::findObject(app, obj, func, ...)
|
||||
QCString app
|
||||
QCString obj
|
||||
QCString func
|
||||
PPCODE:
|
||||
func = canonicalizeSignature(func);
|
||||
QCString foundApp;
|
||||
QCString foundObj;
|
||||
if (!THIS->findObject(app, obj, func, DATA(func, 4), foundApp, foundObj))
|
||||
XSRETURN_UNDEF;
|
||||
PUSHs(QCStringToSV(foundApp));
|
||||
PUSHs(QCStringToSV(foundObj));
|
||||
|
||||
void
|
||||
DCOPClient::emitDCOPSignal(obj, signal, ...)
|
||||
QCString obj
|
||||
QCString signal
|
||||
CODE:
|
||||
signal = canonicalizeSignature(signal);
|
||||
THIS->emitDCOPSignal(obj, signal, DATA(signal, 3));
|
||||
|
||||
bool
|
||||
DCOPClient::isApplicationRegistered(app)
|
||||
QCString app
|
||||
OUTPUT:
|
||||
RETVAL
|
||||
|
||||
QCStringList
|
||||
DCOPClient::registeredApplications()
|
||||
OUTPUT:
|
||||
RETVAL
|
||||
|
||||
QCStringList
|
||||
DCOPClient::remoteObjects(app)
|
||||
QCString app
|
||||
OUTPUT:
|
||||
RETVAL
|
||||
|
||||
QCStringList
|
||||
DCOPClient::remoteInterfaces(app, obj)
|
||||
QCString app
|
||||
QCString obj
|
||||
OUTPUT:
|
||||
RETVAL
|
||||
|
||||
QCStringList
|
||||
DCOPClient::remoteFunctions(app, obj)
|
||||
QCString app
|
||||
QCString obj
|
||||
OUTPUT:
|
||||
RETVAL
|
||||
|
||||
static QCString
|
||||
DCOPClient::normalizeFunctionSignature(sig)
|
||||
QCString sig
|
||||
OUTPUT:
|
||||
RETVAL
|
||||
|
||||
QCString
|
||||
canonicalizeSignature(sig)
|
||||
QCString sig
|
||||
CODE:
|
||||
RETVAL = canonicalizeSignature(sig);
|
||||
OUTPUT:
|
||||
RETVAL
|
@ -0,0 +1,41 @@
|
||||
package DCOP::Object;
|
||||
|
||||
use strict;
|
||||
use vars qw($VERSION $AUTOLOAD);
|
||||
|
||||
$VERSION = '0.01';
|
||||
|
||||
sub AUTOLOAD()
|
||||
{
|
||||
my $funcname;
|
||||
($funcname = $AUTOLOAD) =~ s/.*:://;
|
||||
return if $funcname eq 'DESTROY';
|
||||
my $self = shift;
|
||||
foreach my $func (map {DCOP::canonicalizeSignature $_}
|
||||
@{DCOP::remoteFunctions($self->{CLIENT}, $self->{APP}, $self->{OBJ})})
|
||||
{
|
||||
my $argstr = $func;
|
||||
$argstr =~ s/.*\((.*)\)/$1/;
|
||||
my @args = split /,/, $argstr;
|
||||
next unless $func =~ /^$funcname\(/ && scalar(@args) == scalar(@_);
|
||||
unshift @_, $self->{CLIENT}, $self->{APP}, $self->{OBJ}, "$func";
|
||||
defined wantarray ? goto &DCOP::call : goto &DCOP::send;
|
||||
}
|
||||
die 'Function "', $self->{APP}, '.', $self->{OBJ}, ".$funcname()\" doesn't exist.";
|
||||
}
|
||||
|
||||
sub _app()
|
||||
{
|
||||
my $self = shift;
|
||||
$self->{APP};
|
||||
}
|
||||
|
||||
sub _object()
|
||||
{
|
||||
my $self = shift;
|
||||
$self->{OBJ};
|
||||
}
|
||||
|
||||
1;
|
||||
__END__
|
||||
|
@ -0,0 +1,8 @@
|
||||
Changes
|
||||
DCOP.pm
|
||||
DCOP.xs
|
||||
DCOP/Object.pm
|
||||
Makefile.PL
|
||||
MANIFEST
|
||||
test.pl
|
||||
typemap
|
@ -0,0 +1,42 @@
|
||||
use ExtUtils::MakeMaker;
|
||||
use Config;
|
||||
# See lib/ExtUtils/MakeMaker.pm for details of how to influence
|
||||
# the contents of the Makefile that is written.
|
||||
|
||||
print "Trying to find some configuration information...\n";
|
||||
my $kde_dirs = $ENV{KDEDIRS} || '/usr/local/kde';
|
||||
my $qt_dir = $ENV{QTDIR} || '/usr/lib/qt';
|
||||
my $kde_inc = "$kde_dirs/include";
|
||||
my $kde_lib = "$kde_dirs/lib";
|
||||
my $qt_inc = "$qt_dir/include";
|
||||
my $qt_lib = "$qt_dir/lib";
|
||||
$kde_inc = undef unless -f "$kde_inc/dcopclient.h";
|
||||
$kde_lib = undef unless -f "$kde_lib/libDCOP.$Config{dlext}";
|
||||
$qt_dir = undef unless -f "$qt_inc/qglobal.h";
|
||||
|
||||
print "Path to Qt headers? [$qt_inc]: ";
|
||||
chomp $input, $qt_inc = $input if (($input = <>) =~ /\S/);
|
||||
print "Path to Qt libraries? [$qt_lib]: ";
|
||||
chomp $input, $qt_lib = $input if (($input = <>) =~ /\S/);
|
||||
print "Path to KDE headers? [$kde_inc]: ";
|
||||
chomp $input, $kde_inc = $input if (($input = <>) =~ /\S/);
|
||||
print "Path to KDE libraries? [$kde_lib]: ";
|
||||
chomp $input, $kde_lib = $input if (($input = <>) =~ /\S/);
|
||||
|
||||
WriteMakefile(
|
||||
NAME => 'DCOP',
|
||||
VERSION_FROM => 'DCOP.pm',
|
||||
INC => "-I$qt_inc -I$kde_inc",
|
||||
LIBS => "-L$qt_lib -lqt-mt -L$kde_lib -lkdecore -lDCOP",
|
||||
XS => {'DCOP.xs' => 'DCOP.cpp'},
|
||||
XSOPT => '-C++',
|
||||
CCFLAGS => '-x c++',
|
||||
);
|
||||
|
||||
sub MY::xs_c {
|
||||
package MY;
|
||||
my $hack = shift->SUPER::xs_c(@_);
|
||||
$hack =~ s/\.c/.cpp/g;
|
||||
$hack;
|
||||
}
|
||||
|
@ -0,0 +1,28 @@
|
||||
use ExtUtils::MakeMaker;
|
||||
use Config;
|
||||
# See lib/ExtUtils/MakeMaker.pm for details of how to influence
|
||||
# the contents of the Makefile that is written.
|
||||
|
||||
print "Trying to find some configuration information...\n";
|
||||
my $kde_inc = "@kde_includes@";
|
||||
my $kde_lib = "@kde_libraries@";
|
||||
my $qt_inc = "@qt_includes@";
|
||||
my $qt_lib = "@qt_libraries@";
|
||||
|
||||
WriteMakefile(
|
||||
NAME => 'DCOP',
|
||||
VERSION_FROM => '@srcdir@/DCOP.pm',
|
||||
INC => "-I$qt_inc -I$kde_inc",
|
||||
LIBS => "-L$qt_lib -lqt-mt -L$kde_lib -lkdecore -lDCOP",
|
||||
XS => {'DCOP.xs' => 'DCOP.cpp'},
|
||||
XSOPT => '-C++',
|
||||
CCFLAGS => '-x c++',
|
||||
);
|
||||
|
||||
sub MY::xs_c {
|
||||
package MY;
|
||||
my $hack = shift->SUPER::xs_c(@_);
|
||||
$hack =~ s/\.c/.cpp/g;
|
||||
$hack;
|
||||
}
|
||||
|
@ -0,0 +1,13 @@
|
||||
DCOP Bindings for Perl
|
||||
|
||||
This does need some updating, basic functionality already works quite well
|
||||
|
||||
To install, follow the usual Perl-Module-Installation-Procedure:
|
||||
perl Makefile.PL
|
||||
make
|
||||
make test
|
||||
make install
|
||||
|
||||
Documentation is available in perldoc format embedded into DCOP.pm and
|
||||
after installation it should be accessible via
|
||||
man DCOP
|
@ -0,0 +1,4 @@
|
||||
* Lots of cleanup
|
||||
* More data types
|
||||
* signals/slots
|
||||
* UTF8-safe QString <=> scalar conversions
|
@ -0,0 +1,7 @@
|
||||
KDE_CHECK_PERL(5.005, dcopperl)
|
||||
AC_CONFIG_FILES([ dcopperl/Makefile.PL ], [
|
||||
cd dcopperl
|
||||
perl -I$srcdir Makefile.PL
|
||||
cd ..
|
||||
])
|
||||
|
@ -0,0 +1,123 @@
|
||||
# Before `make install' is performed this script should be runnable with
|
||||
# `make test'. After `make install' it should work as `perl test.pl'
|
||||
|
||||
######################### We start with some black magic to print on failure.
|
||||
|
||||
BEGIN {
|
||||
print <<EOT;
|
||||
Now that you've built the DCOP extension, it's time to run some tests on it.
|
||||
The first of them will just run by themselves, after that, there will be
|
||||
some interactive ones.
|
||||
|
||||
EOT
|
||||
print "Loading...";
|
||||
}
|
||||
|
||||
END {print "failed\n" unless $loaded;}
|
||||
use DCOP;
|
||||
$loaded = 1;
|
||||
print "done\n";
|
||||
|
||||
######################### End of black magic.
|
||||
|
||||
my $ok;
|
||||
|
||||
sub check {
|
||||
my $res = shift;
|
||||
print $res ? "." : "!";
|
||||
$ok = undef unless $res;
|
||||
}
|
||||
|
||||
my ($client, $desk);
|
||||
|
||||
sub attach {
|
||||
$client = new DCOP;
|
||||
check (ref $client) eq "DCOP";
|
||||
check !$client->isAttached();
|
||||
check $client->attach();
|
||||
check $client->isAttached();
|
||||
check $client->detach();
|
||||
check !$client->isAttached();
|
||||
# For now, as register is disabled
|
||||
$client->attach();
|
||||
}
|
||||
|
||||
sub register {
|
||||
check (my $appid = $client->registerAs("perltests"));
|
||||
print "[$appid]";
|
||||
check $client->isRegistered();
|
||||
check $client->appId() eq $appid;
|
||||
check ($appid = $client->registerAs("perltests", undef));
|
||||
print "[$appid]";
|
||||
check $client->isRegistered();
|
||||
check $client->appId() eq $appid;
|
||||
}
|
||||
|
||||
sub query {
|
||||
check (my $list = $client->registeredApplications());
|
||||
print "[$#$list]";
|
||||
check ($list = $client->remoteObjects("kdesktop"));
|
||||
print "[$#$list]";
|
||||
check ($list = $client->remoteInterfaces("kdesktop", "qt"));
|
||||
print "[$#$list]";
|
||||
check ($list = $client->remoteFunctions("kdesktop", "qt"));
|
||||
print "[$#$list]";
|
||||
check grep /^QCStringList functions\(\)$/, @$list;
|
||||
}
|
||||
|
||||
sub calls {
|
||||
check (my $list = $client->call("kdesktop", "qt", "objects()"));
|
||||
print "[$#$list]";
|
||||
check grep m#^qt/kdesktop$#, @$list;
|
||||
}
|
||||
|
||||
sub magic {
|
||||
check ($desk = $client->createObject("kdesktop"));
|
||||
check (ref $desk) eq "DCOP::Object";
|
||||
check (my ($list) = $desk->interfaces());
|
||||
print "[$#$list]";
|
||||
check grep /^KDesktopIface$/, @$list;
|
||||
}
|
||||
|
||||
sub icons {
|
||||
check scalar $desk->selectAll();
|
||||
sleep 1;
|
||||
check scalar $desk->unselectAll();
|
||||
}
|
||||
|
||||
sub saver {
|
||||
check ($desk = $client->createObject("kdesktop")) unless defined $desk;
|
||||
check (my ($saver) = $desk->screenSaver());
|
||||
check (ref $saver) eq "DCOP::Object";
|
||||
check scalar $saver->save();
|
||||
}
|
||||
|
||||
@tests = (
|
||||
["simple attachments", \&attach],
|
||||
# ["full registration", \®ister],
|
||||
["tree queries", \&query],
|
||||
["calls", \&calls],
|
||||
["autoload magic", \&magic],
|
||||
["more autoload magic", \&icons,
|
||||
"The next test should cause all icons on your desktop to be selected\nand deselected again."],
|
||||
["DCOPRefs", \&saver,
|
||||
"The next test should activate your screen saver."],
|
||||
);
|
||||
|
||||
foreach (@tests) {
|
||||
my ($msg, $test, $confirm) = @{$_};
|
||||
if ($confirm) {
|
||||
print "$confirm\nDo you want this test to be performed? [Y/n]";
|
||||
my $answer = <>;
|
||||
next unless ($answer =~ /^\s*$/ || $answer =~ /^[yY]/);
|
||||
}
|
||||
printf "%-25s", $msg;
|
||||
$ok = 1;
|
||||
&$test();
|
||||
unless ($ok) {
|
||||
print "failed\n";
|
||||
exit 1;
|
||||
}
|
||||
print "passed\n";
|
||||
}
|
||||
|
@ -0,0 +1,23 @@
|
||||
TYPEMAP
|
||||
DCOPClient * O_OBJECT
|
||||
QCString T_QCSTRING
|
||||
QCStringList T_QCSTRINGLIST
|
||||
|
||||
INPUT
|
||||
O_OBJECT
|
||||
if(sv_isobject($arg) && (SvTYPE(SvRV($arg)) == SVt_PVMG))
|
||||
$var = ($type)SvIV((SV*)SvRV($arg));
|
||||
else {
|
||||
warn(\"${Package}::$func_name() -- $var is not a blessed SV reference\");
|
||||
XSRETURN_UNDEF;
|
||||
}
|
||||
T_QCSTRING
|
||||
$var = QCStringFromSV($arg);
|
||||
|
||||
OUTPUT
|
||||
O_OBJECT
|
||||
sv_setref_pv( $arg, CLASS, (void*)$var );
|
||||
T_QCSTRING
|
||||
sv_setsv($arg, QCStringToSV($var));
|
||||
T_QCSTRINGLIST
|
||||
sv_setsv($arg, QCStringListToSV($var));
|
@ -0,0 +1,3 @@
|
||||
|
||||
SUBDIRS = shell lib
|
||||
|
@ -0,0 +1,66 @@
|
||||
PYTHON bindings for DCOP
|
||||
========================
|
||||
|
||||
These are the new-style Python DCOP bindings. The way in which the bindings are
|
||||
implemented has changed since KDE 3.1.1.
|
||||
|
||||
|
||||
How they work
|
||||
=============
|
||||
|
||||
The code is divided into two parts:
|
||||
|
||||
pcop.cpp - the C++ interface between Python and DCOP - generates shared library pcop.so
|
||||
which can be imported by Python
|
||||
|
||||
pydcop.py - the Python interface to pcop.cpp
|
||||
|
||||
pcop.cpp includes a header file marshal_funcs.h, which is generated from
|
||||
a data file called marshal_funcs.data by a converter script, gen_marshal_funcs.py
|
||||
|
||||
marshal_funcs.data contains the basic code necessary to marshal and demarshal the different
|
||||
types that DCOP can handle. For example, it codes how to convert a QString for use by Python
|
||||
(in this case, a Python string) and the reverse - what the user may supply in Python when
|
||||
DCOP requires a QString. In addition to the fundemental types, more complex QT classes are
|
||||
coded, such as QRect (which converts to a Python tuple ( (x1,y1), (x2,y2) ) ).
|
||||
|
||||
Documentation is auto-generated out of marshal_funcs.data, creating file marshal_funcs_doc.html,
|
||||
which details how each DCOP type (e.g. QString, QRect, int, QCStringList) is represented in Python.
|
||||
|
||||
In this implementation, each DCOP type is represented by a basic Python type - numeric, tuple, etc.
|
||||
There are no "QT bindings" necessary.
|
||||
|
||||
These bindings allow you to code Python to act as a DCOP client (querying and/or controlling
|
||||
other DCOP applications), or as a DCOP server. This means that you can DCOP-enable Python applications
|
||||
even if they are not QT based.
|
||||
|
||||
If you want to use DCOP in the context of a Python QT application, then there are DCOP bindings included in
|
||||
the PyQT and PyKDE bindings available from:
|
||||
|
||||
http://www.riverbankcomputing.co.uk/
|
||||
|
||||
Examples
|
||||
========
|
||||
|
||||
There are some example Python programs in the test directory.
|
||||
|
||||
Known problems
|
||||
=============
|
||||
|
||||
There is currently a bug which means you must import both pcop and pydcop in your Python programs.
|
||||
This means that a Python program using dcoppython must include:
|
||||
|
||||
import pcop
|
||||
import pydcop
|
||||
|
||||
In that order. If you don't import pcop, a seg fault occurs when the interpreter exits. This, of course, will be
|
||||
fixed once I find out what the hell's going on.
|
||||
|
||||
Authors
|
||||
=======
|
||||
|
||||
The original Python DCOP bindings were written by Torben Weis (weis@kde.org).
|
||||
The current implementation, based on Torben's worked, was written by Julian Rockey (kde@jrockey.com).
|
||||
Julian is also the current maintainer.
|
||||
|
||||
|
@ -0,0 +1,7 @@
|
||||
dcoppython todo..
|
||||
|
||||
Enable/disable debugs
|
||||
Check _object_ and _method_ naming convention
|
||||
Signals
|
||||
ASYNC
|
||||
Threaded server
|
@ -0,0 +1,9 @@
|
||||
KDE_CHECK_PYTHON(1.5)
|
||||
if test -z "$LIBPYTHON" || test -z "$PYTHONINC"; then
|
||||
DO_NOT_COMPILE="$DO_NOT_COMPILE dcoppython"
|
||||
fi
|
||||
|
||||
AC_ARG_VAR([XSLTPROC])
|
||||
AC_ARG_VAR([PYTHON])
|
||||
AC_PATH_PROG([XSLTPROC],[xsltproc],[echo])
|
||||
AC_PATH_PROG([PYTHON],[python])
|
@ -0,0 +1,4 @@
|
||||
|
||||
pyt_DATA = pydcop.py
|
||||
pytdir = $(PYTHONMODDIR)
|
||||
|
@ -0,0 +1,122 @@
|
||||
import pcop
|
||||
|
||||
def registeredApplications():
|
||||
"""Return a list of current DCOP registered applications."""
|
||||
return pcop.app_list()
|
||||
|
||||
def apps():
|
||||
"""Return a list of current DCOP registered applications."""
|
||||
return pcop.app_list()
|
||||
|
||||
def anyAppCalled(appName):
|
||||
"""Return any application instance called appName, or None if none currently registered."""
|
||||
for app in apps():
|
||||
if appName==app or appName+'-'==app[:len(appName)+1]:
|
||||
return DCOPApplication(app)
|
||||
return None
|
||||
|
||||
def registerAs(appid, addpid=1):
|
||||
"""Register the application with DCOP and return the ID. This is needed in order to receive DCOP requests."""
|
||||
return pcop.register_as(appid,addpid)
|
||||
|
||||
def processEvents():
|
||||
"""Process any waiting QT events, then return."""
|
||||
pcop.process_events()
|
||||
|
||||
def connectDCOPSignal(sender,senderObj,signal,receiverObj,slot,vol=1):
|
||||
"""Connect a dcop signal"""
|
||||
return pcop.connect_dcop_signal(sender,senderObj,signal,receiverObj,slot,vol)
|
||||
|
||||
def disconnectDCOPSignal(sender,senderObj,signal,receiverObj,slot):
|
||||
"""Connect a dcop signal"""
|
||||
return pcop.disconnect_dcop_signal(sender,senderObj,signal,receiverObj,slot)
|
||||
|
||||
class DCOPApplication(object):
|
||||
def __init__( self, name ):
|
||||
self.name = name
|
||||
|
||||
def __getattr__( self, item ):
|
||||
if item == "__repr__":
|
||||
return object.__repr__
|
||||
if item == "__str__":
|
||||
return object.__str__
|
||||
if item == "__call__":
|
||||
return object.__call__
|
||||
if item == "_objects_":
|
||||
return pcop.obj_list(self.name)
|
||||
return DCOPObject( self.name, item )
|
||||
|
||||
def _object_(self, object):
|
||||
return DCOPObject( self.name, object )
|
||||
|
||||
class DCOPObject(object):
|
||||
def __init__( self, appname, name ):
|
||||
self.appname = appname
|
||||
self.name = name
|
||||
|
||||
def __repr__( self ):
|
||||
return "DCOPObject(%s,%s)" % ( self.appname, self.name )
|
||||
|
||||
def __str__( self ):
|
||||
return "DCOPObject(%s,%s)" % ( self.appname, self.name )
|
||||
|
||||
def __getattr__( self, item ):
|
||||
if item == "__repr__":
|
||||
return object.__repr__
|
||||
if item == "__str__":
|
||||
return object.__str__
|
||||
if item == "__call__":
|
||||
return object.__call__
|
||||
if item == "_methods_":
|
||||
return pcop.method_list( self.appname, self.name )
|
||||
return DCOPMethod( self.appname, self.name, item )
|
||||
|
||||
def _method_(self, method):
|
||||
return DCOPMethod( self.appname, self.name, method )
|
||||
|
||||
class DCOPMethod(object):
|
||||
def __init__( self, appname, objname, name ):
|
||||
self.appname = appname
|
||||
self.objname = objname
|
||||
self.name = name
|
||||
|
||||
def __repr__( self ):
|
||||
return "DCOPMethod(%s,%s,%s)" % ( self.appname, self.objname, self.name )
|
||||
|
||||
def __str__( self ):
|
||||
return "DCOPMethod(%s,%s,%s)" % ( self.appname, self.objname, self.name )
|
||||
|
||||
def __call__( self, *args ):
|
||||
return pcop.dcop_call( self.appname, self.objname, self.name, args )
|
||||
|
||||
class DCOPServer(object):
|
||||
def __init__( self, appid, addpid = 1):
|
||||
self.app_id = pcop.register_as(appid, addpid)
|
||||
|
||||
|
||||
class DCOPServerObject:
|
||||
"""Inherit from this class to DCOP enabled your object.
|
||||
|
||||
Remember to call the base class constructor, and in your own constructor
|
||||
you should called setMethods to set the methods to DCOP enable.
|
||||
"""
|
||||
|
||||
def __init__(self, objName=None):
|
||||
"""objName is the name of the object. If omitted, it will default to a hex
|
||||
address. It is best to supply it."""
|
||||
if objName:
|
||||
self.dcop_obj = pcop.create_dcop_object(self, objName)
|
||||
else:
|
||||
self.dcop_obj = pcop.create_dcop_object(self)
|
||||
|
||||
def setMethods(self, methods):
|
||||
"""Set the method list for this object.
|
||||
|
||||
methods is a list of tuple pairs. Each pair consists of the
|
||||
method signature and the Python method that handles it.
|
||||
|
||||
For example, setMethods([ ('QString cheeseType()', self.cheese_type),
|
||||
('void setGreatWines(bool perthPink, bool hobartMuddy, bool chateauChunder)')
|
||||
"""
|
||||
pcop.set_method_list(self.dcop_obj, methods)
|
||||
|
@ -0,0 +1,25 @@
|
||||
|
||||
BUILT_SOURCES = marshal_funcs.h
|
||||
CLEANFILES = marshal_funcs.h marshal_funcs_doc.html marshal_funcs_doc.xml
|
||||
|
||||
doc: marshal_funcs_doc.html
|
||||
|
||||
marshal_funcs.h marshal_funcs.xml: $(srcdir)/marshal_funcs.data
|
||||
$(PYTHON) $(srcdir)/gen_marshal_code.py $(srcdir)/marshal_funcs.data marshal_funcs.h marshal_funcs_doc.xml
|
||||
|
||||
marshal_funcs_doc.html: $(srcdir)/marshal_funcs_doc.xsl marshal_funcs_doc.xml
|
||||
$(XSLTPROC) $(srcdir)/marshal_funcs_doc.xsl marshal_funcs_doc.xml >marshal_funcs_doc.html
|
||||
|
||||
INCLUDES = $(PYTHONINC) $(all_includes)
|
||||
|
||||
pythlib_LTLIBRARIES = pcop.la
|
||||
pythlibdir = $(PYTHONMODDIR)/site-packages
|
||||
|
||||
pcop_la_SOURCES = pcop.cpp marshaller.cpp importedmodules.cpp
|
||||
pcop_la_LDFLAGS = $(all_libraries) -module -avoid-version
|
||||
pcop_la_LIBADD = -lDCOP -lkdecore $(LIB_QT)
|
||||
|
||||
noinst_HEADERS = pcop.h marshaller.h marshal_funcs.h importedmodules.h
|
||||
|
||||
|
||||
|
@ -0,0 +1,276 @@
|
||||
#!/usr/bin/env python
|
||||
# Julian Rockey 2003
|
||||
# Generate marshall/demarshal functions from marshal_funcs.data file
|
||||
|
||||
import sys
|
||||
import re
|
||||
|
||||
def cap_first(str):
|
||||
"""Capitalise first letter of string."""
|
||||
return str[0].upper() + str[1:]
|
||||
|
||||
def set_method(attr):
|
||||
"""Return the name for a QT class setter method for an attribute."""
|
||||
return "set" + cap_first(attr)
|
||||
|
||||
class DictMaker:
|
||||
"""Generate code for marshalling/demarshalling types using Python dictionaries."""
|
||||
|
||||
supported_types = ['string']
|
||||
re_dictmap = re.compile("%dict\-map(.*)")
|
||||
re_dictmap_constructor = re.compile("%constructor (.+)")
|
||||
|
||||
def __init__(self):
|
||||
self.attr_list = []
|
||||
self.current_type = None
|
||||
self.operation = None
|
||||
self.constructor = None
|
||||
|
||||
self.type_handlers = {}
|
||||
for type in self.supported_types:
|
||||
self.type_handlers[type] = (eval('self.handle_%s_marsh' % type),
|
||||
eval('self.handle_%s_demarsh' % type))
|
||||
|
||||
def handle_string_marsh(self, attribute):
|
||||
"""Handle marshalling of string item from the dictionary."""
|
||||
return ["if (%s && !PyString_Check(%s)) return false;" % (attribute, attribute),
|
||||
"if (%s) { qobj.%s(QString(PyString_AsString(%s)));" % (attribute, set_method(attribute), attribute),
|
||||
"PyDict_DelItemString(dict,(char*)\"%s\"); } " % (attribute)]
|
||||
|
||||
def handle_string_demarsh(self, attribute):
|
||||
"""Handle demarshalling of string items into the dictionary."""
|
||||
return ["PyObject *%s = PyString_FromString(qobj.%s().utf8().data() );" % (attribute ,attribute),
|
||||
"PyDict_SetItemString(dict, (char*)\"%s\", %s);" % (attribute, attribute)
|
||||
]
|
||||
|
||||
def pre_code_for(self, operation, attribute):
|
||||
|
||||
if operation==MARSHAL:
|
||||
return ["PyObject *%s = PyDict_GetItemString(dict,(char*)\"%s\");" % (attribute, attribute) ]
|
||||
|
||||
return []
|
||||
|
||||
def post_code_for(self, operation, attribute):
|
||||
return []
|
||||
|
||||
def code_for(self, operation, type, attribute):
|
||||
if operation!=None and (type in self.type_handlers):
|
||||
return self.pre_code_for(operation, attribute) + \
|
||||
self.type_handlers[type][not not operation](attribute) + \
|
||||
self.post_code_for(operation, attribute)
|
||||
|
||||
return []
|
||||
|
||||
def set_current_type(self, current_type):
|
||||
self.current_type = current_type
|
||||
self.constructor = "";
|
||||
|
||||
def set_operation(self, operation):
|
||||
if operation in [None, MARSHAL, DEMARSHAL]:
|
||||
self.operation = operation
|
||||
|
||||
def check_dictmap(self, line):
|
||||
|
||||
if self.operation not in [MARSHAL,DEMARSHAL]: return []
|
||||
|
||||
m=self.re_dictmap_constructor.match(line)
|
||||
if m:
|
||||
self.constructor = m.groups()[0]
|
||||
return ['']
|
||||
|
||||
m=self.re_dictmap.match(line)
|
||||
if not m: return []
|
||||
|
||||
if self.operation==MARSHAL:
|
||||
result = ["{",
|
||||
"if (!PyDict_Check(obj)) return false;",
|
||||
"%s qobj%s;" % (self.current_type,self.constructor),
|
||||
"PyObject *dict = PyDict_Copy(obj);"
|
||||
]
|
||||
if self.operation==DEMARSHAL:
|
||||
result = ["{",
|
||||
"PyObject *dict = PyDict_New();",
|
||||
"if (!dict) return NULL;",
|
||||
"%s qobj%s;" % (self.current_type,self.constructor),
|
||||
"(*str) >> qobj;"
|
||||
]
|
||||
|
||||
if m.groups()[0].strip():
|
||||
self.attr_list = [tuple(x.split(':')) for x in m.groups()[0].strip().split(',') ]
|
||||
|
||||
for attribute, type in self.attr_list:
|
||||
result += self.code_for(self.operation, type, attribute)
|
||||
|
||||
if self.operation==MARSHAL:
|
||||
result += ["if (str) (*str) << qobj;",
|
||||
"Py_DECREF(dict);",
|
||||
"return true;",
|
||||
"}"
|
||||
]
|
||||
if self.operation==DEMARSHAL:
|
||||
result += ["return dict;",
|
||||
"}"
|
||||
]
|
||||
|
||||
return result
|
||||
|
||||
class DocType:
|
||||
"""A class to hold documentation information for each type."""
|
||||
|
||||
def __init__(self, type):
|
||||
self.type = type
|
||||
self.demarshal_as = None
|
||||
self.as = []
|
||||
self.info = []
|
||||
|
||||
def add_as(self, as):
|
||||
if self.demarshal_as == None: self.demarshal_as = as
|
||||
self.as += [as]
|
||||
|
||||
def add_info(self,info):
|
||||
self.info += [info]
|
||||
|
||||
def xml(self):
|
||||
return ['<type dcoptype="%s">' % self.type,
|
||||
' <demarshal-as>%s</demarshal-as>' % self.demarshal_as] + \
|
||||
[' <marshal-as>%s</marshal-as>' % as for as in self.as ] + \
|
||||
[' <info>%s</info>' % info for info in self.info ] + \
|
||||
['</type>']
|
||||
|
||||
|
||||
MARSHAL, DEMARSHAL, TOPYOBJ, FROMPYOBJ = 0,1,2,3
|
||||
|
||||
if len(sys.argv)!=4:
|
||||
print "Use: gen_marshal_code.py <input file> <output file> <doc-xml-output file>"
|
||||
raise RuntimeError
|
||||
|
||||
nowt, in_name, code_name, doc_xml_name = tuple(sys.argv)
|
||||
|
||||
##in_name, code_name, doc_xml_name = "marshal_funcs.data", "marshal_funcs.h", "marshal_funcs_doc.xml"
|
||||
|
||||
gen_code_comments = ['/*',
|
||||
' * This code was generated by gen_marshal_code.py',
|
||||
' * Please do not modify, or it\'ll be overwritten!',
|
||||
' */',
|
||||
' ',
|
||||
]
|
||||
|
||||
re_type = re.compile(r"type\: *([^\s]+).*")
|
||||
re_marshDemarsh = re.compile("%% *(de)?marshal *.*")
|
||||
re_tofromPyobj = re.compile("%% *(to|from)_pyobj *.*")
|
||||
re_defaultCode = re.compile("%defaultcode *.*")
|
||||
re_docInfo = re.compile("%doc *([^ ]+) *(.*)")
|
||||
|
||||
in_file = open(in_name,"r")
|
||||
code = []
|
||||
|
||||
types = {}
|
||||
doc_types = {}
|
||||
current_operation = None
|
||||
|
||||
dict_maker = DictMaker()
|
||||
|
||||
for l in in_file.readlines():
|
||||
l=l[:-1]
|
||||
|
||||
# match a "type:" line
|
||||
m=re_type.match(l)
|
||||
if m:
|
||||
current_type = m.groups()[0]
|
||||
types[current_type]={}
|
||||
doc_types[current_type] = DocType(current_type)
|
||||
dict_maker.set_current_type(current_type)
|
||||
continue
|
||||
|
||||
m=re_docInfo.match(l)
|
||||
if m:
|
||||
doc_cmd, rest = m.groups()
|
||||
if doc_cmd=="as":
|
||||
doc_types[current_type].add_as(rest)
|
||||
if doc_cmd=="info":
|
||||
doc_types[current_type].add_info(rest)
|
||||
continue
|
||||
|
||||
# match a "%% marshal" or "%% demarshal" line
|
||||
m=re_marshDemarsh.match(l)
|
||||
if m:
|
||||
if m.groups()[0]:
|
||||
current_operation = DEMARSHAL
|
||||
code.append("PyObject *demarshal_" + current_type + \
|
||||
"(QDataStream *str)")
|
||||
else:
|
||||
current_operation = MARSHAL
|
||||
code.append("bool marshal_" + current_type + \
|
||||
"(PyObject *obj, QDataStream *str)")
|
||||
dict_maker.set_operation(current_operation)
|
||||
continue
|
||||
|
||||
m=re_tofromPyobj.match(l)
|
||||
if m:
|
||||
if m.groups()[0]=='to':
|
||||
current_operation = TOPYOBJ
|
||||
code += ["PyObject *toPyObject_%s(%s val)" % (current_type,current_type)]
|
||||
elif m.groups()[0]=='from':
|
||||
current_operation = FROMPYOBJ
|
||||
code += ["%s fromPyObject_%s(PyObject *obj, bool *ok)" % (current_type,current_type)]
|
||||
continue
|
||||
|
||||
|
||||
if l.strip()=='%%':
|
||||
current_operation = None
|
||||
dict_maker.set_operation(current_operation)
|
||||
|
||||
if current_operation!=None:
|
||||
types[current_type][current_operation]=1
|
||||
|
||||
dict_code = dict_maker.check_dictmap(l)
|
||||
if dict_code:
|
||||
code += dict_code
|
||||
continue
|
||||
|
||||
m=re_defaultCode.match(l)
|
||||
if m:
|
||||
if current_operation==MARSHAL:
|
||||
code += [
|
||||
"{",
|
||||
" bool ok;",
|
||||
" %s qobj=fromPyObject_%s(obj,&ok);" % (current_type,current_type),
|
||||
" if (ok && str) (*str) << qobj;",
|
||||
" return ok;",
|
||||
"}"
|
||||
]
|
||||
continue
|
||||
if current_operation==DEMARSHAL:
|
||||
code += [
|
||||
"{",
|
||||
" %s qobj;" % current_type,
|
||||
" (*str) >> qobj;",
|
||||
" return toPyObject_%s(qobj);" % current_type,
|
||||
"}"
|
||||
]
|
||||
continue
|
||||
|
||||
code.append(l)
|
||||
|
||||
in_file.close()
|
||||
|
||||
code.append("void Marshaller::initFuncs() {")
|
||||
for t in types:
|
||||
if MARSHAL in types[t]:
|
||||
code.append("m_marsh_funcs[\"" + t + "\"]=marshal_" + t + ";")
|
||||
if DEMARSHAL in types[t]:
|
||||
code.append("m_demarsh_funcs[\"" + t + "\"]=demarshal_" + t + ";")
|
||||
code.append("}")
|
||||
|
||||
out_file = open(code_name,"w")
|
||||
out_file.writelines([x + '\n' for x in gen_code_comments])
|
||||
out_file.writelines([x + '\n' for x in code])
|
||||
out_file.close()
|
||||
|
||||
xml_file = file(doc_xml_name,"w")
|
||||
print >>xml_file, '<?xml version="1.0" ?>'
|
||||
print >>xml_file, '<!-- This file was auto-generated by gen_marshal_code.py. Changes will be lost! -->'
|
||||
print >>xml_file, "<types>"
|
||||
[ [xml_file.write(x+"\n") for x in doc.xml()] for doc in doc_types.values() ] # silly one-liner
|
||||
print >>xml_file, "</types>"
|
||||
xml_file.close()
|
@ -0,0 +1,49 @@
|
||||
/***************************************************************************
|
||||
* Copyright (C) 2003 by Julian Rockey (kde@jrockey.com) *
|
||||
* *
|
||||
* 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. *
|
||||
***************************************************************************/
|
||||
|
||||
#include "importedmodules.h"
|
||||
|
||||
#include <kdebug.h>
|
||||
|
||||
namespace PythonDCOP {
|
||||
|
||||
ImportedModules *ImportedModules::m_instance = NULL;
|
||||
|
||||
ImportedModules::ImportedModules() : m_dcop_module(NULL)
|
||||
{
|
||||
m_dcop_module = PyImport_ImportModule( (char*)"pydcop" );
|
||||
if ( !m_dcop_module )
|
||||
kdDebug(70001) << "Could not import pydcop module" << endl;
|
||||
}
|
||||
|
||||
ImportedModules::~ImportedModules()
|
||||
{
|
||||
}
|
||||
|
||||
PyObject* ImportedModules::createDCOPObject( const char* appname, const char* objname )
|
||||
{
|
||||
if ( !m_dcop_module )
|
||||
return 0;
|
||||
|
||||
PyObject* dict = PyModule_GetDict( m_dcop_module );
|
||||
if ( !dict )
|
||||
return 0;
|
||||
|
||||
PyObject* cl = PyDict_GetItemString( dict, (char*)"DCOPObject" );
|
||||
if ( !cl )
|
||||
return 0;
|
||||
|
||||
PyObject* args = PyTuple_New( 2 );
|
||||
PyTuple_SetItem( args, 0, PyString_FromString( appname ) );
|
||||
PyTuple_SetItem( args, 1, PyString_FromString( objname ) );
|
||||
|
||||
return PyObject_CallObject( cl, args );
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,37 @@
|
||||
/***************************************************************************
|
||||
* Copyright (C) 2003 by Julian Rockey (kde@jrockey.com) *
|
||||
* *
|
||||
* 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. *
|
||||
***************************************************************************/
|
||||
|
||||
#ifndef __importedmodules_h__
|
||||
#define __importedmodules_h__
|
||||
|
||||
#include <Python.h>
|
||||
|
||||
namespace PythonDCOP {
|
||||
|
||||
/**
|
||||
* Manages imported Python modules.
|
||||
*/
|
||||
class ImportedModules {
|
||||
public:
|
||||
ImportedModules();
|
||||
~ImportedModules();
|
||||
PyObject *createDCOPObject( const char* appname, const char* objname );
|
||||
PyObject *dcop_module() const { return m_dcop_module; }
|
||||
|
||||
static ImportedModules *instance() { return m_instance; }
|
||||
static void setInstance(ImportedModules *instance) { m_instance = instance; }
|
||||
|
||||
private:
|
||||
PyObject *m_dcop_module;
|
||||
static ImportedModules *m_instance;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
@ -0,0 +1,597 @@
|
||||
// This file contains the C++ code necessary marshal and demarshal
|
||||
// all the _simple_ types that dcoppython can understand.
|
||||
// "Simple" types are types that do not contain other types.
|
||||
// So, int and QString are simple types; QDict, QMap and QStringList are not.
|
||||
// This file is processed by gen_marshal_code.py to produce a header
|
||||
// file, which is included by marshaller.cpp
|
||||
//
|
||||
// Marshalling:
|
||||
// The code in the "marshal" section has the following variables available:
|
||||
// PyObject * obj; // the object to marshal
|
||||
// QDataStream *str; // the stream to marshal to
|
||||
// The function should return true if the object can be marshalled.
|
||||
// str may be NULL. If so, the function should ignore the actually marshalling
|
||||
// and merely return true or false, depending on whether the object _could_
|
||||
// be marshalled.
|
||||
//
|
||||
// Demarshalling:
|
||||
// The code in the "demarshal" section has the following variables available:
|
||||
// QDataStream *str; // the stream to demarshal from
|
||||
// The function should return a PyObject* which is a reference to the
|
||||
// newly created object. Ownership of the reference should be passed to
|
||||
// the caller. The function can return null if for any reason it
|
||||
// could not demarshal.
|
||||
|
||||
type: void
|
||||
%% marshall
|
||||
{
|
||||
Q_UNUSED(str); // stop warnings
|
||||
Q_UNUSED(obj);
|
||||
return true;
|
||||
}
|
||||
%% demarshal
|
||||
{
|
||||
Q_UNUSED(str); // stop warnings
|
||||
Py_INCREF(Py_None);
|
||||
return Py_None;
|
||||
}
|
||||
|
||||
type: bool
|
||||
%doc as int b (1=True, 2=False)
|
||||
%doc info Any Python object is converted to bool by the standard Python truth test.
|
||||
%% from_pyobj
|
||||
{
|
||||
*ok=true;
|
||||
return PyObject_IsTrue(obj);
|
||||
}
|
||||
%% to_pyobj
|
||||
{
|
||||
return PyInt_FromLong(val ? 1 : 0);
|
||||
}
|
||||
%% marshal
|
||||
{
|
||||
if (str) {
|
||||
bool ok;
|
||||
bool b = fromPyObject_bool(obj,&ok);
|
||||
(*str) << (Q_INT8)b;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
%% demarshal
|
||||
{
|
||||
Q_INT8 i;
|
||||
(*str) >> i;
|
||||
return toPyObject_bool(i!=0);
|
||||
}
|
||||
%%
|
||||
|
||||
type:int
|
||||
%doc as int i
|
||||
%% marshal
|
||||
{
|
||||
if (!PyInt_Check(obj)) return false;
|
||||
if (str) {
|
||||
(*str) << (Q_INT32)PyInt_AsLong(obj);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
%% demarshal
|
||||
{
|
||||
Q_INT32 i;
|
||||
(*str) >> i;
|
||||
return PyInt_FromLong( (long)i );
|
||||
}
|
||||
%%
|
||||
|
||||
type:uint
|
||||
%doc as int i
|
||||
%% marshal
|
||||
{
|
||||
if (!PyInt_Check(obj)) return false;
|
||||
if (str) {
|
||||
(*str) << (Q_INT32)PyInt_AsLong(obj);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
%% demarshal
|
||||
{
|
||||
Q_INT32 i;
|
||||
(*str) >> i;
|
||||
return PyInt_FromLong( (long)i );
|
||||
}
|
||||
%%
|
||||
|
||||
type:double
|
||||
%doc as float i
|
||||
%% marshal
|
||||
{
|
||||
if (!PyFloat_Check(obj)) return false;
|
||||
if (str) {
|
||||
(*str) << PyFloat_AsDouble(obj);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
%% demarshal
|
||||
{
|
||||
double d;
|
||||
(*str) >> d;
|
||||
return PyFloat_FromDouble(d);
|
||||
}
|
||||
%%
|
||||
|
||||
type:uchar
|
||||
%doc as str c
|
||||
%doc as int c
|
||||
%% marshal
|
||||
{
|
||||
if (PyString_Check(obj) && PyString_Size(obj)==1) {
|
||||
if (str) {
|
||||
char *c = PyString_AsString(obj);
|
||||
(*str) << (*c);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
if (PyInt_Check(obj)) {
|
||||
if (str) {
|
||||
long l = PyInt_AsLong(obj);
|
||||
Q_UINT8 c = (Q_UINT8)(l & 0xff);
|
||||
(*str) << c;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
%%demarshal
|
||||
{
|
||||
Q_UINT8 c;
|
||||
(*str) >> c;
|
||||
return PyString_FromStringAndSize((const char *)(&c),1);
|
||||
}
|
||||
%%
|
||||
|
||||
type:char
|
||||
%doc as int c
|
||||
%% marshal
|
||||
{
|
||||
if (PyInt_Check(obj)) {
|
||||
if (str) {
|
||||
long l = PyInt_AsLong(obj);
|
||||
Q_INT8 c = (Q_INT8)(l & 0xff);
|
||||
(*str) << c;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
%%demarshal
|
||||
{
|
||||
Q_INT8 c;
|
||||
(*str) >> c;
|
||||
return PyInt_FromLong((long)c);
|
||||
}
|
||||
%%
|
||||
|
||||
|
||||
type:QByteArray
|
||||
%% marshal
|
||||
{
|
||||
PyBufferProcs *pb = obj->ob_type->tp_as_buffer;
|
||||
|
||||
if ( pb && pb->bf_getreadbuffer && pb->bf_getsegcount )
|
||||
{
|
||||
// Get the number of buffer segments
|
||||
int seg_count = (pb->bf_getsegcount)(obj, 0);
|
||||
|
||||
if ( seg_count != 1 )
|
||||
// Can't handle more (or less) than 1 buffer segment
|
||||
// at the moment
|
||||
return false;
|
||||
|
||||
// Get buffer size and data
|
||||
void *data;
|
||||
int size;
|
||||
|
||||
if ( (size = (pb->bf_getreadbuffer)(obj, 0, &data)) < 0 )
|
||||
return false;
|
||||
|
||||
if (str) {
|
||||
QByteArray a;
|
||||
a.setRawData( (const char*)data, size );
|
||||
(*str) << a;
|
||||
a.resetRawData( (const char*)data, size );
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
else
|
||||
// obj does not implement the buffer interface
|
||||
return false;
|
||||
}
|
||||
%% demarshal
|
||||
{
|
||||
// Demarshal to a writable buffer object
|
||||
QByteArray a;
|
||||
(*str) >> a;
|
||||
|
||||
uint size = a.size();
|
||||
char *data = a.data();
|
||||
|
||||
// Create a new buffer object and copy the data.
|
||||
// Don't use PyBuffer_FromMemory() and the likes since
|
||||
// that wouldn't give correct allocation and deallocation.
|
||||
|
||||
PyObject *buffer_obj = PyBuffer_New( size );
|
||||
|
||||
if ( !buffer_obj )
|
||||
return NULL;
|
||||
|
||||
PyBufferProcs *pb = buffer_obj->ob_type->tp_as_buffer;
|
||||
|
||||
void *buffer_data;
|
||||
|
||||
(pb->bf_getwritebuffer)( buffer_obj, 0, &buffer_data );
|
||||
|
||||
for ( uint i = 0; i < size; i++ )
|
||||
((char*)buffer_data)[i] = data[i];
|
||||
|
||||
return buffer_obj;
|
||||
}
|
||||
%%
|
||||
|
||||
type:QString
|
||||
%doc as str s
|
||||
%% marshal
|
||||
{
|
||||
if (!PyString_Check(obj)) return false;
|
||||
if (str) {
|
||||
QString s( PyString_AsString(obj) );
|
||||
(*str) << s;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
%% demarshal
|
||||
{
|
||||
QString s;
|
||||
(*str) >> s;
|
||||
return PyString_FromString( s.utf8().data() );
|
||||
}
|
||||
%%
|
||||
|
||||
type:QCString
|
||||
%doc as str s
|
||||
%% marshal
|
||||
{
|
||||
if (!PyString_Check(obj)) return false;
|
||||
if (str) {
|
||||
QCString s( PyString_AsString(obj) );
|
||||
(*str) << s;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
%% demarshal
|
||||
{
|
||||
QCString s;
|
||||
(*str) >> s;
|
||||
return PyString_FromString( s.data() );
|
||||
}
|
||||
%%
|
||||
|
||||
type:QRect
|
||||
%doc as ( (int x1, int y1), (int x2, int y2) )
|
||||
%doc as ( int x1, int y1, int x2, int y2 )
|
||||
%% from_pyobj
|
||||
{
|
||||
int xp1, yp1, xp2, yp2;
|
||||
QRect r;
|
||||
*ok=false;
|
||||
if (!PyTuple_Check(obj)) return r;
|
||||
if (!PyArg_ParseTuple(obj, (char*)"(ii)(ii)", &xp1, &yp1, &xp2, &yp2) &&
|
||||
!PyArg_ParseTuple(obj, (char*)"iiii", &xp1, &yp1, &xp2, &yp2))
|
||||
return r;
|
||||
r.setCoords( xp1, yp1, xp2, yp2 );
|
||||
*ok=true;
|
||||
return r;
|
||||
}
|
||||
%% to_pyobj
|
||||
{
|
||||
int xp1, yp1, xp2, yp2;
|
||||
val.coords(&xp1,&yp1,&xp2,&yp2);
|
||||
return Py_BuildValue((char*)"(ii)(ii)", xp1, yp1, xp2, yp2);
|
||||
}
|
||||
|
||||
%% marshal
|
||||
%defaultcode
|
||||
%% demarshal
|
||||
%defaultcode
|
||||
%%
|
||||
|
||||
type:QPoint
|
||||
%doc as (int x, int y)
|
||||
%% from_pyobj
|
||||
{
|
||||
int x,y;
|
||||
QPoint p;
|
||||
*ok=false;
|
||||
if (!PyTuple_Check(obj)) return p;
|
||||
if (!PyArg_ParseTuple(obj, (char*)"ii", &x, &y))
|
||||
return p;
|
||||
p.setX(x);
|
||||
p.setY(y);
|
||||
*ok=true;
|
||||
return p;
|
||||
}
|
||||
%% to_pyobj
|
||||
{
|
||||
return Py_BuildValue((char*)"ii", val.x(), val.y() );
|
||||
}
|
||||
%% marshall
|
||||
%defaultcode
|
||||
%% demarshall
|
||||
%defaultcode
|
||||
%%
|
||||
|
||||
type:QSize
|
||||
%doc as (int width, int height)
|
||||
%% from_pyobj
|
||||
{
|
||||
int w,h;
|
||||
QSize sz;
|
||||
*ok=false;
|
||||
if (!PyTuple_Check(obj)) return sz;
|
||||
if (!PyArg_ParseTuple(obj, (char*)"ii", &w, &h))
|
||||
return sz;
|
||||
sz.setWidth(w);
|
||||
sz.setHeight(h);
|
||||
*ok=true;
|
||||
return sz;
|
||||
}
|
||||
%% to_pyobj
|
||||
{
|
||||
return Py_BuildValue((char*)"ii", val.width(), val.height() );
|
||||
}
|
||||
%% marshall
|
||||
%defaultcode
|
||||
%% demarshall
|
||||
%defaultcode
|
||||
%%
|
||||
|
||||
type:QColor
|
||||
%doc as (int red, int green, int blue)
|
||||
%% from_pyobj
|
||||
{
|
||||
int r,g,b;
|
||||
QColor c;
|
||||
*ok=false;
|
||||
if (!PyTuple_Check(obj)) return c;
|
||||
if (!PyArg_ParseTuple(obj, (char*)"iii", &r, &g, &b))
|
||||
return c;
|
||||
c.setRgb(r,g,b);
|
||||
*ok=true;
|
||||
return c;
|
||||
}
|
||||
%% to_pyobj
|
||||
{
|
||||
return Py_BuildValue((char*)"iii", val.red(), val.green(), val.blue() );
|
||||
}
|
||||
%% marshall
|
||||
%defaultcode
|
||||
%% demarshall
|
||||
%defaultcode
|
||||
%%
|
||||
|
||||
type:QPointArray
|
||||
%doc as [ (int x, int y), (int x, int y), (int x, int y), ... ]
|
||||
%% from_pyobj
|
||||
{
|
||||
*ok=false;
|
||||
if (!PyList_Check(obj)) return QPointArray();
|
||||
int size = PyList_Size(obj);
|
||||
QPointArray pa(size);
|
||||
for(int c=0;c<size;c++) {
|
||||
QPoint p = fromPyObject_QPoint(PyList_GetItem(obj,c), ok);
|
||||
if (!*ok) return false;
|
||||
pa.setPoint(c,p);
|
||||
}
|
||||
*ok=true;
|
||||
return pa;
|
||||
}
|
||||
%% to_pyobj
|
||||
{
|
||||
PyObject *obj = PyList_New(val.size());
|
||||
if (!obj) return NULL;
|
||||
for(uint c=0;c<val.size();c++) {
|
||||
PyObject *tuple = toPyObject_QPoint( val.point(c) );
|
||||
PyList_SetItem(obj, c, tuple);
|
||||
// Py_DECREF(tuple);
|
||||
}
|
||||
return obj;
|
||||
}
|
||||
%% marshall
|
||||
%defaultcode
|
||||
%% demarshall
|
||||
%defaultcode
|
||||
%%
|
||||
|
||||
type:QDate
|
||||
%doc as (int year, int month, int day)
|
||||
%% from_pyobj
|
||||
{
|
||||
*ok=false;
|
||||
if (!PyTuple_Check(obj)) return QDate();
|
||||
int y,m,d;
|
||||
if (!PyArg_ParseTuple(obj, (char*)"iii", &y, &m, &d))
|
||||
return QDate();
|
||||
*ok=true;
|
||||
return QDate(y,m,d);
|
||||
}
|
||||
%% to_pyobj
|
||||
{
|
||||
return Py_BuildValue((char*)"iii", val.year(), val.month(), val.day() );
|
||||
}
|
||||
%% marshal
|
||||
%defaultcode
|
||||
%% demarshal
|
||||
%defaultcode
|
||||
%%
|
||||
|
||||
type:QTime
|
||||
%doc as (int hour, int minute, int second=0, int millisecond=0)
|
||||
%% from_pyobj
|
||||
{
|
||||
*ok=false;
|
||||
if (!PyTuple_Check(obj)) return QTime();
|
||||
int h,m,s=0,ms=0;
|
||||
if (!PyArg_ParseTuple(obj, (char*)"ii|ii", &h, &m, &s, &ms))
|
||||
return QTime();
|
||||
*ok=true;
|
||||
return QTime(h,m,s,ms);
|
||||
}
|
||||
%% to_pyobj
|
||||
{
|
||||
return Py_BuildValue((char*)"iiii", val.hour(), val.minute(), val.second(), val.msec() );
|
||||
}
|
||||
%% marshal
|
||||
%defaultcode
|
||||
%% demarshal
|
||||
%defaultcode
|
||||
%%
|
||||
|
||||
type:QDateTime
|
||||
%doc as ( (int year, int month, int day), (int hour, int minute, int second=0, int millsecond=0) )
|
||||
%doc as long unixDate
|
||||
%% from_pyobj
|
||||
{
|
||||
*ok=false;
|
||||
|
||||
if (PyLong_Check(obj)) {
|
||||
*ok=true;
|
||||
QDateTime dt;
|
||||
dt.setTime_t( (uint)PyLong_AsLong(obj) );
|
||||
return dt;
|
||||
}
|
||||
|
||||
if (PyInt_Check(obj)) {
|
||||
*ok=true;
|
||||
QDateTime dt;
|
||||
dt.setTime_t( (uint)PyInt_AsLong(obj) );
|
||||
return dt;
|
||||
}
|
||||
|
||||
PyObject *date_tuple, *time_tuple;
|
||||
if (PyArg_ParseTuple(obj, (char*)"OO", &date_tuple, &time_tuple)) {
|
||||
QDateTime dt;
|
||||
dt.setTime( fromPyObject_QTime(time_tuple, ok) );
|
||||
if (*ok) dt.setDate( fromPyObject_QDate(date_tuple, ok) );
|
||||
return dt;
|
||||
}
|
||||
|
||||
return QDateTime();
|
||||
}
|
||||
%% to_pyobj
|
||||
{
|
||||
PyObject *date_tuple = toPyObject_QDate( val.date() );
|
||||
PyObject *time_tuple = toPyObject_QTime( val.time() );
|
||||
return Py_BuildValue((char*)"OO", date_tuple, time_tuple );
|
||||
}
|
||||
%% marshal
|
||||
%defaultcode
|
||||
%% demarshal
|
||||
%defaultcode
|
||||
%%
|
||||
|
||||
type:KURL
|
||||
%doc as str url
|
||||
%% from_pyobj
|
||||
{
|
||||
*ok=false;
|
||||
if (!PyString_Check(obj)) return KURL();
|
||||
*ok=true;
|
||||
return KURL( QString(PyString_AsString(obj)) );
|
||||
}
|
||||
%% to_pyobj
|
||||
{
|
||||
return PyString_FromString( val.prettyURL().utf8().data() );
|
||||
}
|
||||
%% marshal
|
||||
%defaultcode
|
||||
%% demarshal
|
||||
%defaultcode
|
||||
%%
|
||||
|
||||
type:DCOPRef
|
||||
%% from_pyobj
|
||||
{
|
||||
if (PyInstance_Check(obj) &&
|
||||
PyObject_HasAttrString(obj, (char*)"appname") &&
|
||||
PyObject_HasAttrString(obj, (char*)"name")) {
|
||||
PyObject *appname = PyObject_GetAttrString(obj, (char*)"appname");
|
||||
PyObject *name = PyObject_GetAttrString(obj, (char*)"name");
|
||||
if (PyString_Check(appname) && PyString_Check(name)) {
|
||||
char *c_appname = PyString_AsString(appname);
|
||||
char *c_name = PyString_AsString(name);
|
||||
DCOPRef ref;
|
||||
ref.setRef(QCString(c_appname), QCString(c_name) );
|
||||
Py_DECREF(appname);
|
||||
Py_DECREF(name);
|
||||
*ok=true;
|
||||
return ref;
|
||||
}
|
||||
Py_DECREF(appname);
|
||||
Py_DECREF(name);
|
||||
}
|
||||
*ok=false;
|
||||
return DCOPRef();
|
||||
}
|
||||
%% to_pyobj
|
||||
{
|
||||
if (val.isNull()) {
|
||||
Py_INCREF(Py_None);
|
||||
return Py_None;
|
||||
}
|
||||
return ImportedModules::instance()->createDCOPObject(val.app(), val.object() );
|
||||
}
|
||||
%% marshal
|
||||
%defaultcode
|
||||
%% demarshal
|
||||
%defaultcode
|
||||
%%
|
||||
|
||||
|
||||
// type:DCOPRef
|
||||
// %doc as (str app, str obj, str type)
|
||||
// %doc as (str app, str obj)
|
||||
// %% from_pyobj
|
||||
// {
|
||||
// *ok=false;
|
||||
// char *dcopref_app=NULL, *dcopref_obj=NULL, *dcopref_type=NULL;
|
||||
// if (PyArg_ParseTuple(obj,(char*)"ss|s", &dcopref_app, &dcopref_obj, &dcopref_type)) {
|
||||
// *ok=true;
|
||||
// if (dcopref_type) {
|
||||
// DCOPRef dr(QCString(dcopref_app), QCString(dcopref_obj), QCString(dcopref_type));
|
||||
// return dr;
|
||||
// }
|
||||
// DCOPRef dr(QCString(dcopref_app), QCString(dcopref_obj));
|
||||
// return dr;
|
||||
// }
|
||||
// return DCOPRef();
|
||||
// }
|
||||
// %% to_pyobj
|
||||
// {
|
||||
// return Py_BuildValue((char*)"sss", val.app().data(), val.obj().data(), val.type().data() );
|
||||
// }
|
||||
// %% marshal
|
||||
// %defaultcode
|
||||
// %% demarshal
|
||||
// %defaultcode
|
||||
// %%
|
||||
|
||||
// type:QFont
|
||||
// %% marshal
|
||||
// %constructor ("default")
|
||||
// %dict-map family:string,rawName:string
|
||||
// %% demarshal
|
||||
// %dict-map
|
||||
// %%
|
@ -0,0 +1,40 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
|
||||
version="1.0">
|
||||
|
||||
<xsl:output method="html"/>
|
||||
|
||||
<xsl:template match="/">
|
||||
<html>
|
||||
<body>
|
||||
<xsl:apply-templates/>
|
||||
</body>
|
||||
</html>
|
||||
</xsl:template>
|
||||
|
||||
<xsl:template match="types">
|
||||
<h1>DCOPPython supported types</h1>
|
||||
<xsl:apply-templates/>
|
||||
</xsl:template>
|
||||
|
||||
<xsl:template match="type">
|
||||
<h2><xsl:value-of select="@dcoptype"/></h2>
|
||||
<xsl:apply-templates select="demarshal-as"/>
|
||||
<div>Argument of form:</div>
|
||||
<div style="margin-left: 2cm">
|
||||
<xsl:for-each select="marshal-as">
|
||||
<b><xsl:value-of select="."/></b>
|
||||
</xsl:for-each>
|
||||
</div>
|
||||
<xsl:apply-templates select="info"/>
|
||||
</xsl:template>
|
||||
|
||||
<xsl:template match="demarshal-as">
|
||||
<div>Returns as: <b><xsl:apply-templates/></b></div>
|
||||
</xsl:template>
|
||||
|
||||
<xsl:template match="info">
|
||||
<div><xsl:apply-templates/></div>
|
||||
</xsl:template>
|
||||
|
||||
</xsl:stylesheet>
|
@ -0,0 +1,169 @@
|
||||
/***************************************************************************
|
||||
* Copyright (C) 2003 by Julian Rockey *
|
||||
* linux@jrockey.com *
|
||||
* *
|
||||
* 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. *
|
||||
***************************************************************************/
|
||||
|
||||
#include "marshaller.h"
|
||||
|
||||
#include "pcop.h"
|
||||
#include "importedmodules.h"
|
||||
|
||||
#include <qdatastream.h>
|
||||
|
||||
#include <qrect.h>
|
||||
#include <qfont.h>
|
||||
#include <qcolor.h>
|
||||
#include <qpointarray.h>
|
||||
#include <qdatetime.h>
|
||||
#include <dcopref.h>
|
||||
|
||||
#include <kurl.h>
|
||||
|
||||
#if PY_VERSION_HEX < 0x02050000
|
||||
typedef int Py_ssize_t;
|
||||
#endif
|
||||
|
||||
namespace PythonDCOP {
|
||||
|
||||
#include "marshal_funcs.h"
|
||||
|
||||
Marshaller::Marshaller()
|
||||
{
|
||||
initFuncs();
|
||||
}
|
||||
|
||||
Marshaller::~Marshaller()
|
||||
{
|
||||
}
|
||||
|
||||
bool Marshaller::marsh_private(const PCOPType &type,
|
||||
PyObject *obj,
|
||||
QDataStream *str) const
|
||||
{
|
||||
|
||||
QString ty = type.type();
|
||||
|
||||
if (ty=="QStringList")
|
||||
return marshalList(PCOPType("QString"), obj, str);
|
||||
if (ty=="QCStringList")
|
||||
return marshalList(PCOPType("QCString"), obj, str);
|
||||
if (ty=="QValueList" && type.leftType())
|
||||
return marshalList(*type.leftType(), obj, str);
|
||||
if (ty=="QMap" && type.leftType() && type.rightType())
|
||||
return marshalDict(*type.leftType(), *type.rightType(), obj, str);
|
||||
|
||||
if (!m_marsh_funcs.contains(ty)) return false;
|
||||
return m_marsh_funcs[ty](obj,str);
|
||||
}
|
||||
|
||||
PyObject *Marshaller::demarsh_private(const PCOPType &type,
|
||||
QDataStream *str) const
|
||||
{
|
||||
QString ty = type.type();
|
||||
|
||||
if (ty=="QStringList")
|
||||
return demarshalList(PCOPType("QString"), str);
|
||||
if (ty=="QCStringList")
|
||||
return demarshalList(PCOPType("QCString"), str);
|
||||
if (ty=="QValueList" && type.leftType())
|
||||
return demarshalList(*type.leftType(), str);
|
||||
if (ty=="QMap" && type.leftType() && type.rightType())
|
||||
return demarshalDict(*type.leftType(), *type.rightType(), str);
|
||||
|
||||
if (!m_demarsh_funcs.contains(ty)) {
|
||||
Py_INCREF(Py_None);
|
||||
return Py_None;
|
||||
}
|
||||
|
||||
PyObject *result = m_demarsh_funcs[ty](str);
|
||||
if (!result) {
|
||||
Py_INCREF(Py_None);
|
||||
return Py_None;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
bool Marshaller::marshalList(const PCOPType &list_type,
|
||||
PyObject *obj,
|
||||
QDataStream *str) const {
|
||||
if (!PyList_Check(obj)) return false;
|
||||
|
||||
int count = PyList_Size(obj);
|
||||
|
||||
for(int c=0;c<count;c++)
|
||||
if (!list_type.isMarshallable( PyList_GetItem(obj,c) ) )
|
||||
return false;
|
||||
|
||||
if (str) {
|
||||
(*str) << (Q_INT32)count;
|
||||
for(int c=0; c<count; c++)
|
||||
list_type.marshal( PyList_GetItem(obj,c), *str );
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
PyObject *Marshaller::demarshalList(const PCOPType &list_type,
|
||||
QDataStream *str) const {
|
||||
Q_UINT32 count;
|
||||
(*str) >> count;
|
||||
|
||||
PyObject *obj = PyList_New(count);
|
||||
for(Q_UINT32 c=0;c<count;c++) {
|
||||
PyList_SetItem(obj, c, list_type.demarshal(*str));
|
||||
}
|
||||
return obj;
|
||||
}
|
||||
|
||||
bool Marshaller::marshalDict(const PCOPType &key_type,
|
||||
const PCOPType &value_type,
|
||||
PyObject *obj,
|
||||
QDataStream *str) const {
|
||||
if (!PyDict_Check(obj)) return false;
|
||||
|
||||
|
||||
Py_ssize_t c=0;
|
||||
PyObject *key, *val;
|
||||
while (PyDict_Next(obj, &c, &key, &val)==1)
|
||||
if (!key_type.isMarshallable(key) ||
|
||||
!value_type.isMarshallable(val))
|
||||
return false;
|
||||
|
||||
if (str) {
|
||||
Q_INT32 count = (Q_INT32)PyDict_Size(obj);
|
||||
(*str) << count;
|
||||
c=0;
|
||||
while (PyDict_Next(obj, &c, &key, &val)==1) {
|
||||
key_type.marshal(key,*str);
|
||||
value_type.marshal(val,*str);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
PyObject *Marshaller::demarshalDict(const PCOPType &key_type,
|
||||
const PCOPType &value_type,
|
||||
QDataStream *str) const {
|
||||
PyObject *obj = PyDict_New();
|
||||
Q_INT32 count;
|
||||
(*str) >> count;
|
||||
for(Q_INT32 c=0;c<count;c++) {
|
||||
PyObject *key = key_type.demarshal(*str);
|
||||
PyObject *value = value_type.demarshal(*str);
|
||||
PyDict_SetItem(obj,key,value);
|
||||
}
|
||||
return obj;
|
||||
}
|
||||
|
||||
|
||||
Marshaller *Marshaller::m_instance = new Marshaller;
|
||||
|
||||
|
||||
}
|
||||
|
@ -0,0 +1,71 @@
|
||||
/***************************************************************************
|
||||
* Copyright (C) 2003 by Julian Rockey *
|
||||
* linux@jrockey.com *
|
||||
* *
|
||||
* 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. *
|
||||
***************************************************************************/
|
||||
|
||||
#ifndef __marshaller_h__
|
||||
#define __marshaller_h__
|
||||
|
||||
#include <qmap.h>
|
||||
#include <Python.h>
|
||||
#include <qstring.h>
|
||||
|
||||
class QDataStream;
|
||||
|
||||
namespace PythonDCOP {
|
||||
// class Marshaller;
|
||||
class PCOPType;
|
||||
|
||||
class Marshaller {
|
||||
public:
|
||||
Marshaller();
|
||||
~Marshaller();
|
||||
bool marshal(const PCOPType &type, PyObject *obj, QDataStream &str) const
|
||||
{ return marsh_private(type,obj,&str); }
|
||||
bool canMarshal(const PCOPType &type, PyObject *obj) const
|
||||
{ return marsh_private(type,obj,NULL); }
|
||||
bool marshalList(const PCOPType &list_type, PyObject *obj, QDataStream *str) const;
|
||||
PyObject *demarshal(const PCOPType &type, QDataStream &str) const
|
||||
{ return demarsh_private(type, &str); }
|
||||
PyObject *demarshalList(const PCOPType &list_type, QDataStream *str) const;
|
||||
bool marshalDict(const PCOPType &key_type, const PCOPType &value_type,
|
||||
PyObject *obj, QDataStream *str) const;
|
||||
PyObject *demarshalDict(const PCOPType &key_type,
|
||||
const PCOPType &value_type,
|
||||
QDataStream *str) const;
|
||||
static Marshaller *instance() { return m_instance; }
|
||||
protected:
|
||||
QMap<QString,bool(*)(PyObject*,QDataStream*)> m_marsh_funcs;
|
||||
QMap<QString,PyObject*(*)(QDataStream*)> m_demarsh_funcs;
|
||||
|
||||
static Marshaller *m_instance;
|
||||
|
||||
void initFuncs();
|
||||
private:
|
||||
bool marsh_private(const PCOPType &type,
|
||||
PyObject *obj,
|
||||
QDataStream *str) const;
|
||||
PyObject *demarsh_private(const PCOPType &type,
|
||||
QDataStream *str) const;
|
||||
|
||||
|
||||
|
||||
};
|
||||
|
||||
// bool marshall_bool(PyObject *obj, QDataStream *str);
|
||||
// bool marshall_int(PyObject *obj, QDataStream *str);
|
||||
// bool marshall_uint(PyObject *obj, QDataStream *str);
|
||||
// bool marshall_double(PyObject *obj, QDataStream *str);
|
||||
// bool marshall_QByteArray(PyObject *obj, QDataStream *str);
|
||||
// bool marshall_QString(PyObject *obj, QDataStream *str);
|
||||
// bool marshall_QCString(PyObject *obj, QDataStream *str);
|
||||
|
||||
|
||||
}
|
||||
|
||||
#endif
|
@ -0,0 +1,770 @@
|
||||
/***************************************************************************
|
||||
* Copyright (C) 2003 by Julian Rockey (linux@jrockey.com) *
|
||||
* Original code by Torben Weis *
|
||||
* *
|
||||
* 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. *
|
||||
***************************************************************************/
|
||||
|
||||
|
||||
#include "pcop.h"
|
||||
|
||||
#include <kdebug.h>
|
||||
|
||||
#include <qapplication.h>
|
||||
#include <qcstring.h>
|
||||
#include <qdatastream.h>
|
||||
#include <qfile.h>
|
||||
#include <qtextstream.h>
|
||||
#include <qstring.h>
|
||||
|
||||
#include <dcopclient.h>
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
#include "marshaller.h"
|
||||
#include "importedmodules.h"
|
||||
|
||||
namespace PythonDCOP {
|
||||
|
||||
PCOPObject::PCOPObject(PyObject *py_obj) :
|
||||
DCOPObject(), m_py_obj(py_obj)
|
||||
{
|
||||
m_methods.setAutoDelete(true);
|
||||
}
|
||||
|
||||
PCOPObject::PCOPObject(PyObject *py_obj, const char *objid) :
|
||||
DCOPObject(QCString(objid)), m_py_obj(py_obj)
|
||||
{
|
||||
m_methods.setAutoDelete(true);
|
||||
}
|
||||
|
||||
PCOPObject::~PCOPObject()
|
||||
{
|
||||
}
|
||||
|
||||
bool PCOPObject::process(const QCString &fun, const QByteArray &data,
|
||||
QCString& replyType, QByteArray &replyData)
|
||||
{
|
||||
bool result = py_process(fun,data,replyType,replyData);
|
||||
if (PyErr_Occurred()) {
|
||||
kdDebug(70001) << "Error! About to print..." << endl;
|
||||
PyErr_Print();
|
||||
kdDebug(70001) << "About to clear..." << endl;
|
||||
PyErr_Clear();
|
||||
kdDebug(70001) << "Error handled." << endl;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
bool PCOPObject::py_process(const QCString &fun, const QByteArray &data,
|
||||
QCString& replyType, QByteArray &replyData)
|
||||
{
|
||||
|
||||
kdDebug(70001) << "PCOPObject::process - fun=" << fun << " replyType=" << replyType << endl;
|
||||
|
||||
PCOPMethod *meth = matchMethod(fun);
|
||||
if (!meth) {
|
||||
kdDebug(70001) << "Could not match method name" << endl;
|
||||
}
|
||||
|
||||
if (meth) {
|
||||
|
||||
kdDebug(70001) << "m_py_obj=" << m_py_obj << " meth->name=" << meth->name() << " meth->name.data=" << meth->name().data() << endl;
|
||||
if (meth->name().isNull()) { kdDebug(70001) << "meth name is null" << endl; return false; }
|
||||
// if (!PyObject_HasAttrString(m_py_obj, meth->name().data())) {
|
||||
// kdDebug(70001) << "Method registered, but no python method found" << endl;
|
||||
// return false;
|
||||
// }
|
||||
|
||||
QDataStream str_arg(data, IO_ReadOnly);
|
||||
PyObject *args = PyTuple_New( meth->paramCount() );
|
||||
for(int c=0;c<meth->paramCount();c++) {
|
||||
kdDebug(70001) << "Demarshalling type: " << meth->param(c)->signature() << endl;
|
||||
PyObject *arg = meth->param(c)->demarshal(str_arg);
|
||||
if (!arg) {
|
||||
kdDebug(70001) << "Failed to demarshall an argument" << endl;
|
||||
return false;
|
||||
}
|
||||
PyTuple_SetItem(args, c, arg );
|
||||
}
|
||||
|
||||
kdDebug(70001) << "args is " << PyTuple_Size(args) << " long" << endl;
|
||||
|
||||
// PyObject *method = PyObject_GetAttrString(m_py_obj, meth->name().data() );
|
||||
PyObject *method = meth->pythonMethod();
|
||||
if (!PyCallable_Check(method)) {
|
||||
kdDebug(70001) << "Expected a callable object, but didn't get one!" << endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
// PyObject *function = PyMethod_Function(method);
|
||||
// PyObject *self = PyMethod_Self(method);
|
||||
// Py_INCREF(self);
|
||||
// PyTuple_SetItem(args, 0, self );
|
||||
// PyObject *result = PyObject_CallObject(function, args);
|
||||
|
||||
// Py_DECREF(method);
|
||||
if (PyMethod_Self(method)==NULL)
|
||||
kdDebug(70001) << "Warning: self is null!" << endl;
|
||||
|
||||
kdDebug(70001) << "About to call object.." << endl;
|
||||
PyObject *result = PyObject_CallObject(method, args);
|
||||
kdDebug(70001) << "Finished calling object." << endl;
|
||||
|
||||
if (result) {
|
||||
replyType = meth->type()->signature();
|
||||
PCOPType repl(replyType);
|
||||
if (repl.isMarshallable(result)) {
|
||||
QDataStream str_repl(replyData, IO_WriteOnly);
|
||||
repl.marshal(result,str_repl);
|
||||
Py_DECREF(result);
|
||||
return true;
|
||||
} else {
|
||||
Py_DECREF(result);
|
||||
kdDebug(70001) << "Result of python method was not marshallable into " << replyType << endl;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else {
|
||||
kdDebug(70001) << "null result from python method call" << endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return DCOPObject::process(fun,data,replyType,replyData);
|
||||
|
||||
}
|
||||
|
||||
bool PCOPObject::setMethodList(QAsciiDict<PyObject> meth_list) {
|
||||
bool ok = true;
|
||||
|
||||
for(QAsciiDictIterator<PyObject> it(meth_list);
|
||||
it.current(); ++it) {
|
||||
|
||||
PCOPMethod *meth = NULL;
|
||||
if (ok) {
|
||||
meth = new PCOPMethod(QCString(it.currentKey()));
|
||||
|
||||
if (!meth || !meth->setPythonMethod(it.current())) {
|
||||
if (meth) delete meth;
|
||||
meth=NULL;
|
||||
m_methods.clear();
|
||||
ok=false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Py_DECREF(it.current());
|
||||
if (meth) m_methods.insert(meth->signature(),meth);
|
||||
}
|
||||
|
||||
return ok;
|
||||
}
|
||||
|
||||
QCStringList PCOPObject::functions() {
|
||||
QCStringList funcs = DCOPObject::functions();
|
||||
for(QAsciiDictIterator<PCOPMethod> it(m_methods);
|
||||
it.current(); ++it) {
|
||||
PCOPMethod *meth = it.current();
|
||||
QCString func = meth->type()->signature();
|
||||
func += ' ';
|
||||
func += meth->signature();
|
||||
funcs << func;
|
||||
}
|
||||
return funcs;
|
||||
}
|
||||
|
||||
/**
|
||||
* For testing
|
||||
*/
|
||||
PyObject *PCOPObject::methodList() {
|
||||
PyObject *result = PyList_New(m_methods.count());
|
||||
int c=0;
|
||||
for(QAsciiDictIterator<PCOPMethod> it(m_methods);
|
||||
it.current(); ++it, ++c) {
|
||||
PyObject *tuple = PyTuple_New(2);
|
||||
PyList_SetItem(result, c, tuple);
|
||||
PyTuple_SetItem(tuple, 0, PyString_FromString(it.currentKey() ) );
|
||||
PyTuple_SetItem(tuple, 1, it.current()->pythonMethod() );
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
PCOPMethod *PCOPObject::matchMethod(const QCString &fun) {
|
||||
return m_methods.find(fun);
|
||||
}
|
||||
|
||||
|
||||
PCOPType::PCOPType( const QCString& type )
|
||||
{
|
||||
m_leftType = NULL;
|
||||
m_rightType = NULL;
|
||||
|
||||
int pos = type.find( '<' );
|
||||
if ( pos == -1 )
|
||||
{
|
||||
m_type = type;
|
||||
return;
|
||||
}
|
||||
|
||||
int pos2 = type.findRev( '>' );
|
||||
if ( pos2 == -1 )
|
||||
return;
|
||||
|
||||
m_type = type.left( pos );
|
||||
|
||||
// There may be no more than 2 types in the bracket
|
||||
int komma = type.find( ',', pos + 1 );
|
||||
if ( komma == -1 )
|
||||
{
|
||||
m_leftType = new PCOPType( type.mid( pos + 1, pos2 - pos - 1 ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
m_leftType = new PCOPType( type.mid( pos + 1, komma - pos - 1 ) );
|
||||
m_rightType = new PCOPType( type.mid( komma + 1, pos2 - komma - 1 ) );
|
||||
}
|
||||
}
|
||||
|
||||
PCOPType::~PCOPType()
|
||||
{
|
||||
if (m_leftType) delete m_leftType;
|
||||
if (m_rightType) delete m_rightType;
|
||||
}
|
||||
|
||||
QCString PCOPType::signature() const
|
||||
{
|
||||
QCString str = m_type;
|
||||
if ( m_leftType )
|
||||
{
|
||||
str += "<";
|
||||
str += m_leftType->signature();
|
||||
|
||||
if ( m_rightType )
|
||||
{
|
||||
str += ",";
|
||||
str += m_rightType->signature();
|
||||
}
|
||||
|
||||
str += ">";
|
||||
}
|
||||
|
||||
return str;
|
||||
}
|
||||
|
||||
bool PCOPType::marshal( PyObject* obj, QDataStream& str ) const
|
||||
{
|
||||
return Marshaller::instance()->marshal(*this, obj, str);
|
||||
}
|
||||
|
||||
bool PCOPType::isMarshallable( PyObject *obj ) const
|
||||
{
|
||||
return Marshaller::instance()->canMarshal(*this, obj);
|
||||
}
|
||||
|
||||
PyObject* PCOPType::demarshal( QDataStream& str ) const
|
||||
{
|
||||
return Marshaller::instance()->demarshal(*this, str);
|
||||
}
|
||||
|
||||
PCOPMethod::PCOPMethod( const QCString& signature ) :
|
||||
m_py_method(NULL)
|
||||
{
|
||||
|
||||
m_type = 0;
|
||||
m_params.setAutoDelete( TRUE );
|
||||
|
||||
// Find the space that separates the type from the name
|
||||
int k = signature.find( ' ' );
|
||||
if ( k == -1 )
|
||||
return;
|
||||
|
||||
// Create the return type from the string
|
||||
m_type = new PCOPType( signature.left( k ) );
|
||||
|
||||
// Find the brackets
|
||||
int i = signature.find( '(' );
|
||||
if ( i == -1 )
|
||||
return;
|
||||
int j = signature.find( ')' );
|
||||
if ( j == -1 )
|
||||
return;
|
||||
|
||||
// Extract the name
|
||||
m_name = signature.mid( k + 1, i - k - 1 );
|
||||
|
||||
// Strip the parameters
|
||||
QCString p = signature.mid( i + 1, j - i - 1 ).stripWhiteSpace();
|
||||
|
||||
if ( !p.isEmpty() ) {
|
||||
// Make the algorithm terminate
|
||||
p += ",";
|
||||
|
||||
// Iterate over the parameters
|
||||
int level = 0;
|
||||
int start = 0;
|
||||
int len = p.length();
|
||||
for( int i = 0; i < len; ++i )
|
||||
{
|
||||
// Found a comma? Then we reached the end of a parameter
|
||||
if ( p[i] == ',' && level == 0 )
|
||||
{
|
||||
// Find the space that separates name from type.
|
||||
int space = p.find( ' ', start );
|
||||
|
||||
if ( space == -1 || space > i ) // unnamed parameter
|
||||
space = i;
|
||||
|
||||
PCOPType* type = new PCOPType( p.mid( start, space - start ) );
|
||||
m_params.append( type );
|
||||
|
||||
// Start of the next parameter
|
||||
start = i + 1;
|
||||
}
|
||||
else if ( p[i] == '<' )
|
||||
++level;
|
||||
else if ( p[i] == '>' )
|
||||
--level;
|
||||
}
|
||||
}
|
||||
|
||||
m_signature = m_name;
|
||||
m_signature += "(";
|
||||
|
||||
QListIterator<PCOPType> it( m_params );
|
||||
for( ; it.current(); ++it )
|
||||
{
|
||||
if ( !it.atFirst() )
|
||||
m_signature += ',';
|
||||
m_signature += it.current()->signature();
|
||||
}
|
||||
|
||||
m_signature += ")";
|
||||
|
||||
}
|
||||
|
||||
PCOPMethod::~PCOPMethod()
|
||||
{
|
||||
delete m_type;
|
||||
if (m_py_method) {
|
||||
Py_DECREF(m_py_method);
|
||||
}
|
||||
}
|
||||
|
||||
bool PCOPMethod::setPythonMethod(PyObject *method) {
|
||||
if (method && PyMethod_Check(method)) {
|
||||
|
||||
if (m_py_method) {
|
||||
Py_DECREF(m_py_method);
|
||||
}
|
||||
|
||||
m_py_method = method;
|
||||
Py_INCREF(m_py_method);
|
||||
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
int PCOPMethod::paramCount() const
|
||||
{
|
||||
return m_params.count();
|
||||
}
|
||||
|
||||
PCOPType* PCOPMethod::param( int i )
|
||||
{
|
||||
return m_params.at( i );
|
||||
}
|
||||
|
||||
const PCOPType* PCOPMethod::param( int i ) const
|
||||
{
|
||||
return ((PCOPMethod*)this)->m_params.at( i );
|
||||
}
|
||||
|
||||
PCOPClass::PCOPClass( const QCStringList& methods )
|
||||
{
|
||||
m_methods.setAutoDelete( true );
|
||||
|
||||
QCStringList::ConstIterator it = methods.begin();
|
||||
for( ; it != methods.end(); ++it )
|
||||
{
|
||||
PCOPMethod* m = new PCOPMethod( *it );
|
||||
m_methods.insert( m->m_name, m );
|
||||
}
|
||||
}
|
||||
|
||||
PCOPClass::~PCOPClass()
|
||||
{
|
||||
}
|
||||
|
||||
const PCOPMethod* PCOPClass::method( const QCString &name, PyObject *argTuple )
|
||||
{
|
||||
if ( !argTuple )
|
||||
return m_methods[ name ];
|
||||
|
||||
QAsciiDictIterator<PCOPMethod> it( m_methods );
|
||||
for (; it.current(); ++it )
|
||||
if ( it.currentKey() == name &&
|
||||
it.current()->paramCount() == PyTuple_Size( argTuple ) )
|
||||
{
|
||||
// ok, name and argument count match, now check if the python
|
||||
// can be marshalled to the qt/dcop type
|
||||
|
||||
PCOPMethod *m = it.current();
|
||||
|
||||
bool fullMatch = true;
|
||||
|
||||
for ( int i = 0; i < m->paramCount(); ++i )
|
||||
if ( !m->param( i )->isMarshallable( PyTuple_GetItem( argTuple, i ) ) )
|
||||
{
|
||||
fullMatch = false;
|
||||
break;
|
||||
}
|
||||
|
||||
if ( fullMatch )
|
||||
return m;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
// Client
|
||||
|
||||
Client::Client() : m_dcop(NULL), m_qapp(NULL)
|
||||
{
|
||||
ImportedModules::setInstance( new ImportedModules );
|
||||
int argc = 0;
|
||||
char **argv = NULL;
|
||||
m_qapp = new QApplication(argc,argv,false);
|
||||
}
|
||||
|
||||
Client::~Client()
|
||||
{
|
||||