summaryrefslogtreecommitdiffstats
path: root/korundum/rubylib/korundum
diff options
context:
space:
mode:
authortoma <toma@283d02a7-25f6-0310-bc7c-ecb5cbfe19da>2009-11-25 17:56:58 +0000
committertoma <toma@283d02a7-25f6-0310-bc7c-ecb5cbfe19da>2009-11-25 17:56:58 +0000
commit90825e2392b2d70e43c7a25b8a3752299a933894 (patch)
treee33aa27f02b74604afbfd0ea4f1cfca8833d882a /korundum/rubylib/korundum
downloadtdebindings-90825e2392b2d70e43c7a25b8a3752299a933894.tar.gz
tdebindings-90825e2392b2d70e43c7a25b8a3752299a933894.zip
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-ecb5cbfe19da
Diffstat (limited to 'korundum/rubylib/korundum')
-rw-r--r--korundum/rubylib/korundum/Korundum.cpp1183
-rw-r--r--korundum/rubylib/korundum/Makefile.am10
-rw-r--r--korundum/rubylib/korundum/configure.in.in15
-rw-r--r--korundum/rubylib/korundum/kdehandlers.cpp1428
-rw-r--r--korundum/rubylib/korundum/lib/KDE/Korundum.rb1
-rw-r--r--korundum/rubylib/korundum/lib/KDE/Makefile.am5
-rw-r--r--korundum/rubylib/korundum/lib/KDE/korundum.rb1391
-rw-r--r--korundum/rubylib/korundum/lib/Makefile.am1
8 files changed, 4034 insertions, 0 deletions
diff --git a/korundum/rubylib/korundum/Korundum.cpp b/korundum/rubylib/korundum/Korundum.cpp
new file mode 100644
index 00000000..6cd3045a
--- /dev/null
+++ b/korundum/rubylib/korundum/Korundum.cpp
@@ -0,0 +1,1183 @@
+/***************************************************************************
+ Korundum.cpp - Runtime for KDE services, DCOP etc
+ -------------------
+ begin : Sun Sep 28 2003
+ copyright : (C) 2003-2004 by Richard Dale
+ email : Richard_Dale@tipitina.demon.co.uk
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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 <qobject.h>
+#include <qstringlist.h>
+#include <qmap.h>
+#include <qdatastream.h>
+
+#include <kdeversion.h>
+#include <dcopclient.h>
+#include <dcopobject.h>
+#include <dcopref.h>
+#include <kapplication.h>
+#include <kurl.h>
+#if KDE_VERSION >= 0x030200
+#include <kconfigskeleton.h>
+#endif
+#include <kio/global.h>
+#include <kparts/browserextension.h>
+#include <kde_terminal_interface.h>
+
+#include <ruby.h>
+
+#include <marshall.h>
+#include <qtruby.h>
+#include <smokeruby.h>
+#include <smoke.h>
+
+extern "C" {
+extern VALUE qt_internal_module;
+extern VALUE kconfigskeleton_class;
+extern VALUE kconfigskeleton_itemenum_choice_class;
+extern VALUE kio_udsatom_class;
+extern VALUE konsole_part_class;
+extern VALUE set_obj_info(const char * className, smokeruby_object * o);
+extern void set_kde_resolve_classname(const char * (*kde_resolve_classname) (Smoke*, int, void *));
+extern const char * kde_resolve_classname(Smoke* smoke, int classId, void * ptr);
+};
+
+extern TypeHandler KDE_handlers[];
+extern void install_handlers(TypeHandler *);
+extern Smoke *qt_Smoke;
+
+
+static VALUE kde_internal_module;
+Marshall::HandlerFn getMarshallFn(const SmokeType &type);
+
+/*
+ Copy items from the stack to the stream, each item has a corresponding description in the
+ args array of MocArguments. Used for marshalling the args to DCOP calls and sends, emitting
+ DCOP signals, and converting the return value of a DCOP slot to a stream.
+*/
+static void
+smokeStackToStream(Marshall *m, Smoke::Stack stack, QDataStream* stream, int items, MocArgument* args)
+{
+ for(int i = 0; i < items; i++) {
+ switch(args[i].argType) {
+ case xmoc_bool:
+ *stream << stack[i].s_bool;
+ break;
+ case xmoc_int:
+ *stream << stack[i].s_int;
+ break;
+ case xmoc_double:
+ *stream << stack[i].s_double;
+ break;
+ case xmoc_charstar:
+ *stream << (char *) stack[i].s_voidp;
+ break;
+ case xmoc_QString:
+ {
+ QString temp((const QString&) *((QString *) stack[i].s_voidp));
+ *stream << temp;
+ }
+ break;
+ default:
+ {
+ const SmokeType &t = args[i].st;
+ switch(t.elem()) {
+ case Smoke::t_bool:
+ *stream << stack[i].s_bool;
+ break;
+ case Smoke::t_char:
+ *stream << stack[i].s_char;
+ break;
+ case Smoke::t_uchar:
+ *stream << stack[i].s_uchar;
+ break;
+ case Smoke::t_short:
+ *stream << stack[i].s_short;
+ break;
+ case Smoke::t_ushort:
+ *stream << stack[i].s_ushort;
+ break;
+ case Smoke::t_int:
+ *stream << stack[i].s_int;
+ break;
+ case Smoke::t_uint:
+ *stream << stack[i].s_uint;
+ break;
+ case Smoke::t_long:
+ *stream << stack[i].s_long;
+ break;
+ case Smoke::t_ulong:
+ *stream << stack[i].s_ulong;
+ break;
+ case Smoke::t_float:
+ *stream << stack[i].s_float;
+ break;
+ case Smoke::t_double:
+ *stream << stack[i].s_double;
+ break;
+ case Smoke::t_enum:
+ m->unsupported();
+ break;
+ case Smoke::t_class:
+ case Smoke::t_voidp:
+ {
+ // Special case any types which are in the Smoke runtime, but
+ // don't have QDataStream '<<' methods
+ if (strcmp(t.name(), "QCString") == 0) {
+ QCString temp((const QCString&) *((QCString *) stack[i].s_voidp));
+ *stream << temp;
+ break;
+ } else if (strcmp(t.name(), "QCStringList") == 0) {
+ QCStringList temp((const QCStringList&) *((QCStringList *) stack[i].s_voidp));
+ *stream << temp;
+ break;
+ } else if (strcmp(t.name(), "QStringList") == 0) {
+ QStringList temp((const QStringList&) *((QStringList *) stack[i].s_voidp));
+ *stream << temp;
+ break;
+ } else if (strcmp(t.name(), "KURL::List") == 0) {
+ KURL::List temp((const KURL::List&) *((KURL::List *) stack[i].s_voidp));
+ *stream << temp;
+ break;
+ } else if (strcmp(t.name(), "QMap<QCString,DCOPRef>") == 0) {
+ QMap<QCString,DCOPRef> temp((const QMap<QCString,DCOPRef>&) *((QMap<QCString,DCOPRef>*) stack[i].s_voidp));
+ *stream << temp;
+ break;
+ }
+
+ // Look for methods of the form: QDataStream & operator<<(QDataStream&, const MyClass&)
+ Smoke::Index meth = t.smoke()->findMethod("QGlobalSpace", "operator<<##");
+ Smoke::Index ix;
+ if (meth > 0) {
+ ix = t.smoke()->methodMaps[meth].method;
+ ix = -ix; // turn into ambiguousMethodList index
+ while (t.smoke()->ambiguousMethodList[ix]) {
+ Smoke::Method &method = t.smoke()->methods[t.smoke()->ambiguousMethodList[ix]];
+ QString refType("const ");
+ refType += t.name();
+ refType += "&";
+ if ( strcmp( "QDataStream&",
+ t.smoke()->types[t.smoke()->argumentList[method.args+0]].name ) == 0
+ && strcmp( refType.latin1(),
+ t.smoke()->types[t.smoke()->argumentList[method.args+1]].name ) == 0 )
+ {
+ Smoke::ClassFn fn = t.smoke()->classes[method.classId].classFn;
+ Smoke::StackItem local_stack[3];
+ local_stack[1].s_voidp = stream;
+ local_stack[2].s_voidp = stack[i].s_voidp;
+ // Call the QDataStream marshaller write method
+ // with the instance to be marshalled
+ (*fn)(method.method, 0, local_stack);
+ break;
+ }
+ ix++;
+ }
+ }
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ }
+ }
+ return;
+}
+
+/*
+ Copy items from the stream to the stack, each item has a corresponding description in the
+ args array of MocArguments. Used for marshalling the arguments to a DCOP slot invocation,
+ and for converting a dcop reply to a ruby value.
+*/
+static void
+smokeStackFromStream(Marshall *m, Smoke::Stack stack, QDataStream* stream, int items, MocArgument* args)
+{
+ for(int i = 0; i < items; i++) {
+ switch(args[i].argType) {
+ case xmoc_bool:
+ {
+ *stream >> stack[i].s_bool;
+ break;
+ }
+ case xmoc_int:
+ {
+ *stream >> stack[i].s_int;
+ break;
+ }
+ case xmoc_double:
+ *stream >> stack[i].s_double;
+ break;
+ case xmoc_charstar:
+ *stream >> (char *&) stack[i].s_voidp;
+ break;
+ case xmoc_QString:
+ {
+ QString temp;
+ *stream >> temp;
+ stack[i].s_voidp = new QString(temp);
+ }
+ break;
+ default: // case xmoc_ptr:
+ {
+ const SmokeType &t = args[i].st;
+ switch(t.elem()) {
+ case Smoke::t_bool:
+ {
+ *stream >> stack[i].s_bool;
+ break;
+ }
+ case Smoke::t_char:
+ {
+ *stream >> stack[i].s_char;
+ break;
+ }
+ case Smoke::t_uchar:
+ {
+ *stream >> stack[i].s_uchar;
+ break;
+ }
+ case Smoke::t_short:
+ {
+ *stream >> stack[i].s_short;
+ break;
+ }
+ case Smoke::t_ushort:
+ {
+ *stream >> stack[i].s_ushort;
+ break;
+ }
+ case Smoke::t_int:
+ {
+ *stream >> stack[i].s_int;
+ break;
+ }
+ case Smoke::t_uint:
+ {
+ *stream >> stack[i].s_uint;
+ break;
+ }
+ case Smoke::t_long:
+ {
+ *stream >> stack[i].s_long;
+ break;
+ }
+ case Smoke::t_ulong:
+ {
+ *stream >> stack[i].s_ulong;
+ break;
+ }
+ case Smoke::t_float:
+ *stream >> stack[i].s_float;
+ break;
+ case Smoke::t_double:
+ *stream >> stack[i].s_double;
+ break;
+ case Smoke::t_enum:
+ m->unsupported();
+ break;
+ case Smoke::t_class:
+ case Smoke::t_voidp:
+ {
+ // Special case any types which are in the Smoke runtime, but
+ // don't have QDataStream '>>' methods
+ if (strcmp(t.name(), "QCString") == 0) {
+ QCString temp;
+ *stream >> temp;
+ stack[i].s_voidp = new QCString(temp);
+ break;
+ } else if (strcmp(t.name(), "QCStringList") == 0) {
+ QCStringList temp;
+ *stream >> temp;
+ stack[i].s_voidp = new QCStringList(temp);
+ break;
+ } else if (strcmp(t.name(), "QStringList") == 0) {
+ QStringList temp;
+ *stream >> temp;
+ stack[i].s_voidp = new QStringList(temp);
+ break;
+ } else if (strcmp(t.name(), "KURL::List") == 0) {
+ KURL::List temp;
+ *stream >> temp;
+ stack[i].s_voidp = new KURL::List(temp);
+ break;
+ } else if (strcmp(t.name(), "QMap<QCString,DCOPRef>") == 0) {
+ QMap<QCString,DCOPRef> temp;
+ *stream >> temp;
+ stack[i].s_voidp = new QMap<QCString,DCOPRef>(temp);
+ break;
+ }
+
+ // First construct an instance to read the QDataStream into,
+ // so look for a no args constructor
+ Smoke::Index ctorId = t.smoke()->idMethodName(t.name());
+ Smoke::Index ctorMeth = t.smoke()->findMethod(t.classId(), ctorId);
+ Smoke::Index ctor = t.smoke()->methodMaps[ctorMeth].method;
+ if(ctor < 1) {
+ stack[i].s_voidp = 0;
+ m->unsupported();
+ break; // Ambiguous or non-existent method, shouldn't happen with a no arg constructor
+ }
+ // Okay, ctor is the constructor. Time to call it.
+ Smoke::StackItem ctor_stack[1];
+ ctor_stack[0].s_voidp = 0;
+ Smoke::ClassFn classfn = t.smoke()->classes[t.classId()].classFn;
+ (*classfn)(t.smoke()->methods[ctor].method, 0, ctor_stack);
+ stack[i].s_voidp = ctor_stack[0].s_voidp;
+
+ // Look for methods of the form: QDataStream & operator>>(QDataStream&, MyClass&)
+ Smoke::Index meth = t.smoke()->findMethod("QGlobalSpace", "operator>>##");
+ Smoke::Index ix;
+ if (meth > 0) {
+ ix = t.smoke()->methodMaps[meth].method;
+ ix = -ix; // turn into ambiguousMethodList index
+ while (t.smoke()->ambiguousMethodList[ix]) {
+ Smoke::Method &method = t.smoke()->methods[t.smoke()->ambiguousMethodList[ix]];
+ QString refType(t.name());
+ refType += "&";
+ if ( strcmp( "QDataStream&",
+ t.smoke()->types[t.smoke()->argumentList[method.args+0]].name ) == 0
+ && strcmp( refType.latin1(),
+ t.smoke()->types[t.smoke()->argumentList[method.args+1]].name ) == 0 )
+ {
+ Smoke::ClassFn fn = t.smoke()->classes[method.classId].classFn;
+ Smoke::StackItem local_stack[3];
+ local_stack[1].s_voidp = stream;
+ local_stack[2].s_voidp = stack[i].s_voidp;
+ // Call the QDataStream marshaller read method
+ // on the instance to be marshalled
+ (*fn)(method.method, 0, local_stack);
+ break;
+ }
+ ix++;
+ }
+ }
+ }
+ break;
+ }
+ }
+ }
+ }
+}
+
+/*
+ Converts a QByteArray returned from a DCOP call to a ruby value.
+*/
+class DCOPReturn : public Marshall {
+ MocArgument * _replyType;
+ Smoke::Stack _stack;
+ VALUE * _result;
+public:
+ DCOPReturn(QDataStream & retval, VALUE * result, VALUE replyType)
+ {
+ _result = result;
+ VALUE temp = rb_funcall(qt_internal_module, rb_intern("getMocArguments"), 1, replyType);
+ Data_Get_Struct(rb_ary_entry(temp, 1), MocArgument, _replyType);
+ _stack = new Smoke::StackItem[1];
+ smokeStackFromStream(this, _stack, &retval, 1, _replyType);
+ Marshall::HandlerFn fn = getMarshallFn(type());
+ (*fn)(this);
+ }
+
+ SmokeType type() {
+ return _replyType[0].st;
+ }
+ Marshall::Action action() { return Marshall::ToVALUE; }
+ Smoke::StackItem &item() { return _stack[0]; }
+ VALUE * var() {
+ return _result;
+ }
+
+ void unsupported()
+ {
+ rb_raise(rb_eArgError, "Cannot handle '%s' as DCOP return-type", type().name());
+ }
+ Smoke *smoke() { return type().smoke(); }
+
+ void next() {}
+
+ bool cleanup() { return false; }
+
+ ~DCOPReturn()
+ {
+ delete[] _stack;
+ }
+};
+
+class DCOPCall : public Marshall {
+ VALUE _obj;
+ QCString & _remFun;
+ int _items;
+ VALUE *_sp;
+ QByteArray *_data;
+ QDataStream *_stream;
+ int _id;
+ MocArgument *_args;
+ bool _useEventLoop;
+ int _timeout;
+ int _cur;
+ Smoke::Stack _stack;
+ VALUE _result;
+ bool _called;
+public:
+ DCOPCall(VALUE obj, QCString & remFun, int items, VALUE *sp, VALUE args, bool useEventLoop, int timeout) :
+ _obj(obj), _remFun(remFun), _items(items), _sp(sp),
+ _useEventLoop(useEventLoop), _timeout(timeout), _cur(-1), _called(false)
+ {
+ _data = new QByteArray();
+ _stream = new QDataStream(*_data, IO_WriteOnly);
+ Data_Get_Struct(rb_ary_entry(args, 1), MocArgument, _args);
+ _stack = new Smoke::StackItem[_items];
+ _result = Qnil;
+ }
+
+ ~DCOPCall()
+ {
+ delete[] _stack;
+ delete _data;
+ delete _stream;
+ }
+ const MocArgument &arg() { return _args[_cur]; }
+ SmokeType type() { return arg().st; }
+ Marshall::Action action() { return Marshall::FromVALUE; }
+ Smoke::StackItem &item() { return _stack[_cur]; }
+ VALUE * var() {
+ if(_cur < 0) return &_result;
+ return _sp + _cur;
+ }
+
+ void unsupported()
+ {
+ rb_raise(rb_eArgError, "Cannot handle '%s' as a DCOP call argument", type().name());
+ }
+
+ Smoke *smoke() { return type().smoke(); }
+
+ void dcopCall()
+ {
+ if(_called) return;
+ _called = true;
+
+ smokeStackToStream(this, _stack, _stream, _items, _args);
+ smokeruby_object *o = value_obj_info(_obj);
+ DCOPRef * dcopRef = (DCOPRef *) o->smoke->cast(o->ptr, o->classId, o->smoke->idClass("DCOPRef"));
+ DCOPClient* dc = dcopRef->dcopClient();
+ QCString replyType;
+ QByteArray dataReceived;
+#if KDE_VERSION >= 0x030200
+ bool ok = dc->call(dcopRef->app(), dcopRef->obj(), _remFun, *_data, replyType, dataReceived, _useEventLoop, _timeout);
+#else
+ bool ok = dc->call(dcopRef->app(), dcopRef->obj(), _remFun, *_data, replyType, dataReceived, _useEventLoop);
+#endif
+
+ if (!ok) {
+ // Note that a failed dcop call returns 'nil', not 'false'
+ _result = Qnil;
+ return;
+ } else if (replyType == "void" || replyType == "ASYNC") {
+ _result = Qtrue;
+ return;
+ }
+
+ QDataStream ds(dataReceived, IO_ReadOnly);
+
+ if (replyType == "QValueList<DCOPRef>") {
+ // Special case QValueList<DCOPRef> as a QDataStream marshaller
+ // isn't in the Smoke runtime
+ QValueList<DCOPRef> valuelist;
+ ds >> valuelist;
+ _result = rb_ary_new();
+ for (QValueListIterator<DCOPRef> it = valuelist.begin(); it != valuelist.end(); ++it) {
+ void *p = new DCOPRef(*it);
+ VALUE obj = getPointerObject(p);
+
+ if (obj == Qnil) {
+ smokeruby_object * o = ALLOC(smokeruby_object);
+ o->classId = qt_Smoke->idClass("DCOPRef");
+ o->smoke = qt_Smoke;
+ o->ptr = p;
+ o->allocated = true;
+ obj = set_obj_info("KDE::DCOPRef", o);
+ }
+
+ rb_ary_push(_result, obj);
+ }
+ } else if (replyType == "QValueList<QCString>") {
+ // And special case this type too
+ QValueList<QCString> propertyList;
+ ds >> propertyList;
+ _result = rb_ary_new();
+ for (QValueListIterator<QCString> it = propertyList.begin(); it != propertyList.end(); ++it) {
+ rb_ary_push(_result, rb_str_new2((const char *) *it));
+ }
+ } else if (replyType == "QValueList<int>") {
+ // And special case this type too
+ QValueList<int> propertyList;
+ ds >> propertyList;
+ _result = rb_ary_new();
+ for (QValueListIterator<int> it = propertyList.begin(); it != propertyList.end(); ++it) {
+ rb_ary_push(_result, INT2NUM(*it));
+ }
+ } else if (replyType == "QMap<QString,DCOPRef>") {
+ // And another..
+ QMap<QString,DCOPRef> actionMap;
+ ds >> actionMap;
+ _result = rb_hash_new();
+
+ QMap<QString,DCOPRef>::Iterator it;
+ for (it = actionMap.begin(); it != actionMap.end(); ++it) {
+ void *p = new DCOPRef(it.data());
+ VALUE obj = getPointerObject(p);
+
+ if (obj == Qnil) {
+ smokeruby_object * o = ALLOC(smokeruby_object);
+ o->classId = qt_Smoke->idClass("DCOPRef");
+ o->smoke = qt_Smoke;
+ o->ptr = p;
+ o->allocated = true;
+ obj = set_obj_info("KDE::DCOPRef", o);
+ }
+
+ rb_hash_aset(_result, rb_str_new2(it.key().latin1()), obj);
+ }
+ } else {
+ DCOPReturn dcopReturn(ds, &_result, rb_str_new2((const char *) replyType));
+ }
+ }
+
+ void next()
+ {
+ int oldcur = _cur;
+ _cur++;
+
+ while(!_called && _cur < _items) {
+ Marshall::HandlerFn fn = getMarshallFn(type());
+ (*fn)(this);
+ _cur++;
+ }
+
+ dcopCall();
+ _cur = oldcur;
+ }
+
+ bool cleanup() { return true; }
+};
+
+class DCOPSend : public Marshall {
+ VALUE _obj;
+ QCString & _remFun;
+ QByteArray *_data;
+ QDataStream *_stream;
+ int _id;
+ MocArgument *_args;
+ int _items;
+ VALUE *_sp;
+ int _cur;
+ VALUE * _result;
+ Smoke::Stack _stack;
+ bool _called;
+public:
+ DCOPSend(VALUE obj, QCString & remFun, int items, VALUE *sp, VALUE args, VALUE * result) :
+ _obj(obj), _remFun(remFun), _items(items), _sp(sp), _cur(-1), _result(result), _called(false)
+ {
+ _data = new QByteArray();
+ _stream = new QDataStream(*_data, IO_WriteOnly);
+ Data_Get_Struct(rb_ary_entry(args, 1), MocArgument, _args);
+ _stack = new Smoke::StackItem[_items];
+ }
+
+ ~DCOPSend()
+ {
+ delete[] _stack;
+ delete _data;
+ delete _stream;
+ }
+ const MocArgument &arg() { return _args[_cur]; }
+ SmokeType type() { return arg().st; }
+ Marshall::Action action() { return Marshall::FromVALUE; }
+ Smoke::StackItem &item() { return _stack[_cur]; }
+ VALUE * var() { return _sp + _cur; }
+
+ void unsupported()
+ {
+ rb_raise(rb_eArgError, "Cannot handle '%s' as a DCOP send argument", type().name());
+ }
+
+ Smoke *smoke() { return type().smoke(); }
+
+ void dcopSend()
+ {
+ if(_called) return;
+ _called = true;
+
+ smokeStackToStream(this, _stack, _stream, _items, _args);
+ smokeruby_object *o = value_obj_info(_obj);
+ DCOPRef * dcopRef = (DCOPRef *) o->smoke->cast(o->ptr, o->classId, o->smoke->idClass("DCOPRef"));
+ DCOPClient* dc = dcopRef->dcopClient();
+ bool ok = dc->send(dcopRef->app(), dcopRef->obj(), _remFun, *_data);
+ *_result = (ok ? Qtrue : Qfalse);
+ }
+
+ void next()
+ {
+ int oldcur = _cur;
+ _cur++;
+
+ while(!_called && _cur < _items) {
+ Marshall::HandlerFn fn = getMarshallFn(type());
+ (*fn)(this);
+ _cur++;
+ }
+
+ dcopSend();
+ _cur = oldcur;
+ }
+
+ bool cleanup() { return true; }
+};
+
+class EmitDCOPSignal : public Marshall {
+ VALUE _obj;
+ const char * _signalName;
+ QByteArray *_data;
+ QDataStream *_stream;
+ int _id;
+ MocArgument *_args;
+ VALUE *_sp;
+ int _items;
+ int _cur;
+ Smoke::Stack _stack;
+ bool _called;
+public:
+ EmitDCOPSignal(VALUE obj, const char * signalName, int items, VALUE *sp, VALUE args) :
+ _obj(obj), _signalName(signalName), _sp(sp), _items(items), _cur(-1), _called(false)
+ {
+ _data = new QByteArray();
+ _stream = new QDataStream(*_data, IO_WriteOnly);
+ Data_Get_Struct(rb_ary_entry(args, 1), MocArgument, _args);
+ _stack = new Smoke::StackItem[_items];
+ }
+
+ ~EmitDCOPSignal()
+ {
+ delete[] _stack;
+ delete _stream;
+ delete _data;
+ }
+ const MocArgument &arg() { return _args[_cur]; }
+ SmokeType type() { return arg().st; }
+ Marshall::Action action() { return Marshall::FromVALUE; }
+ Smoke::StackItem &item() { return _stack[_cur]; }
+ VALUE * var() { return _sp + _cur; }
+
+ void unsupported()
+ {
+ rb_raise(rb_eArgError, "Cannot handle '%s' as a DCOP signal argument", type().name());
+ }
+
+ Smoke *smoke() { return type().smoke(); }
+
+ void emitSignal()
+ {
+ if(_called) return;
+ _called = true;
+
+ smokeStackToStream(this, _stack, _stream, _items, _args);
+ smokeruby_object *o = value_obj_info(_obj);
+ DCOPObject * dcopObject = (DCOPObject *) o->smoke->cast(o->ptr, o->classId, o->smoke->idClass("DCOPObject"));
+ dcopObject->emitDCOPSignal(_signalName, *_data);
+ }
+
+ void next()
+ {
+ int oldcur = _cur;
+ _cur++;
+
+ while(!_called && _cur < _items) {
+ Marshall::HandlerFn fn = getMarshallFn(type());
+ (*fn)(this);
+ _cur++;
+ }
+
+ emitSignal();
+ _cur = oldcur;
+ }
+
+ bool cleanup() { return true; }
+};
+
+/*
+ Converts a ruby value returned by a DCOP slot invocation to a QByteArray
+*/
+class DCOPReplyValue : public Marshall {
+ MocArgument * _replyType;
+ Smoke::Stack _stack;
+ VALUE * _result;
+public:
+ DCOPReplyValue(QByteArray & retval, VALUE * result, VALUE replyType)
+ {
+ QDataStream _retval(retval, IO_WriteOnly);
+ _result = result;
+ Data_Get_Struct(rb_ary_entry(replyType, 1), MocArgument, _replyType);
+ _stack = new Smoke::StackItem[1];
+ Marshall::HandlerFn fn = getMarshallFn(type());
+ (*fn)(this);
+ smokeStackToStream(this, _stack, &_retval, 1, _replyType);
+ }
+
+ SmokeType type() {
+ return _replyType[0].st;
+ }
+ Marshall::Action action() { return Marshall::FromVALUE; }
+ Smoke::StackItem &item() { return _stack[0]; }
+ VALUE * var() {
+ return _result;
+ }
+
+ void unsupported()
+ {
+ rb_raise(rb_eArgError, "Cannot handle '%s' as DCOP reply-type", type().name());
+ }
+ Smoke *smoke() { return type().smoke(); }
+
+ void next() {}
+
+ bool cleanup() { return false; }
+
+ ~DCOPReplyValue() {
+ delete[] _stack;
+ }
+};
+
+class InvokeDCOPSlot : public Marshall {
+ VALUE _obj;
+ ID _slotname;
+ int _items;
+ MocArgument * _args;
+ QDataStream * _stream;
+ const char * _replyTypeName;
+ VALUE _replyType;
+ QByteArray * _retval;
+ int _cur;
+ bool _called;
+ VALUE * _sp;
+ Smoke::Stack _stack;
+public:
+ const MocArgument &arg() { return _args[_cur]; }
+ SmokeType type() { return arg().st; }
+ Marshall::Action action() { return Marshall::ToVALUE; }
+ Smoke::StackItem &item() { return _stack[_cur]; }
+ VALUE * var() { return _sp + _cur; }
+ Smoke *smoke() { return type().smoke(); }
+ bool cleanup() { return false; }
+
+ void unsupported()
+ {
+ rb_raise(rb_eArgError, "Cannot handle '%s' as DCOP slot argument\n", type().name());
+ }
+
+ void copyArguments()
+ {
+ smokeStackFromStream(this, _stack, _stream, _items, _args);
+ return;
+ }
+
+ void invokeSlot()
+ {
+ if (_called) {
+ return;
+ }
+ _called = true;
+ VALUE result = rb_funcall2(_obj, _slotname, _items, _sp);
+
+ if ( strcmp(_replyTypeName, "QValueList<DCOPRef>") == 0
+ && TYPE(result) == T_ARRAY )
+ {
+ // Special case QValueList<DCOPRef> as a QDataStream marshaller
+ // isn't in the Smoke runtime
+ QValueList<DCOPRef> windowList;
+
+ for (long i = 0; i < RARRAY(result)->len; i++) {
+ VALUE item = rb_ary_entry(result, i);
+ smokeruby_object *o = value_obj_info(item);
+ if( !o || !o->ptr)
+ continue;
+ void * ptr = o->ptr;
+ ptr = o->smoke->cast(ptr, o->classId, o->smoke->idClass("DCOPRef"));
+ windowList.append((DCOPRef)*(DCOPRef*)ptr);
+ }
+ QDataStream retval(*_retval, IO_WriteOnly);
+ retval << windowList;
+ } else if ( strcmp(_replyTypeName, "QValueList<QCString>") == 0
+ && TYPE(result) == T_ARRAY )
+ {
+ // And special case this type too
+ QValueList<QCString> propertyList;
+
+ for (long i = 0; i < RARRAY(result)->len; i++) {
+ VALUE item = rb_ary_entry(result, i);
+ propertyList.append(QCString(StringValuePtr(item)));
+ }
+ QDataStream retval(*_retval, IO_WriteOnly);
+ retval << propertyList;
+ } else if ( strcmp(_replyTypeName, "QMap<QString,DCOPRef>") == 0
+ && TYPE(result) == T_HASH )
+ {
+ // And another..
+ QMap<QString,DCOPRef> actionMap;
+ // Convert the ruby hash to an array of key/value arrays
+ VALUE temp = rb_funcall(result, rb_intern("to_a"), 0);
+
+ for (long i = 0; i < RARRAY(temp)->len; i++) {
+ VALUE action = rb_ary_entry(rb_ary_entry(temp, i), 0);
+ VALUE item = rb_ary_entry(rb_ary_entry(temp, i), 1);
+
+ smokeruby_object *o = value_obj_info(item);
+ if( !o || !o->ptr)
+ continue;
+ void * ptr = o->ptr;
+ ptr = o->smoke->cast(ptr, o->classId, o->smoke->idClass("DCOPRef"));
+
+ actionMap[QString(StringValuePtr(action))] = (DCOPRef)*(DCOPRef*)ptr;
+ }
+ QDataStream retval(*_retval, IO_WriteOnly);
+ retval << actionMap;
+ } else if (_replyType != Qnil) {
+ DCOPReplyValue dcopReply(*_retval, &result, _replyType);
+ }
+ }
+
+ void next()
+ {
+ int oldcur = _cur;
+ _cur++;
+
+ while(!_called && _cur < _items) {
+ Marshall::HandlerFn fn = getMarshallFn(type());
+ (*fn)(this);
+ _cur++;
+ }
+
+ invokeSlot();
+ _cur = oldcur;
+ }
+
+ InvokeDCOPSlot(VALUE obj, ID slotname, VALUE args, QByteArray& data, VALUE replyTypeName, VALUE replyType, QByteArray& returnValue) :
+ _obj(obj), _slotname(slotname), _replyType(replyType), _cur(-1), _called(false)
+ {
+ _replyTypeName = StringValuePtr(replyTypeName);
+ _items = NUM2INT(rb_ary_entry(args, 0));
+ _stream = new QDataStream(data, IO_ReadOnly);
+ _retval = &returnValue;
+
+ Data_Get_Struct(rb_ary_entry(args, 1), MocArgument, _args);
+ _sp = ALLOC_N(VALUE, _items);
+ _stack = new Smoke::StackItem[_items];
+
+ copyArguments();
+ }
+
+ ~InvokeDCOPSlot() {
+ delete[] _stack;
+ delete _stream;
+ for(int i=0;i<_items;++i) {
+ free(_sp++);
+ }
+ }
+};
+
+extern "C" {
+extern void Init_qtruby();
+extern void set_new_kde(VALUE (*new_kde) (int, VALUE *, VALUE));
+extern void set_kconfigskeletonitem_immutable(VALUE (*kconfigskeletonitem_immutable) (VALUE));
+extern void set_kde_resolve_classname(const char * (*kde_resolve_classname) (Smoke*, int, void *));
+extern const char * kde_resolve_classname(Smoke* smoke, int classId, void * ptr);
+extern VALUE new_qt(int argc, VALUE * argv, VALUE klass);
+extern VALUE qt_module;
+extern VALUE qt_internal_module;
+extern VALUE qt_base_class;
+extern VALUE kde_module;
+extern VALUE kio_module;
+extern VALUE kparts_module;
+extern VALUE khtml_module;
+
+VALUE
+getdcopinfo(VALUE self, QString & signalname)
+{
+ VALUE member = rb_funcall( kde_internal_module,
+ rb_intern("fullSignalName"),
+ 2, self, rb_str_new2(signalname) );
+ signalname.setLatin1(StringValuePtr(member));
+ return rb_funcall( qt_internal_module,
+ rb_intern("getMocArguments"),
+ 1, member );
+}
+
+VALUE
+k_dcop_signal(int argc, VALUE * argv, VALUE self)
+{
+ VALUE dcopObject = rb_funcall(kde_module, rb_intern("createDCOPObject"), 1, self);
+
+ QString signalname(rb_id2name(rb_frame_last_func()));
+ VALUE args = getdcopinfo(self, signalname);
+
+ if(args == Qnil) return Qfalse;
+
+ EmitDCOPSignal signal(dcopObject, signalname.latin1(), argc, argv, args);
+ signal.next();
+
+ return Qtrue;
+}
+
+static VALUE
+dcop_functions(VALUE self)
+{
+ VALUE dcopObject = rb_funcall(kde_module, rb_intern("createDCOPObject"), 1, self);
+ return rb_funcall(dcopObject, rb_intern("functions"), 0);
+}
+
+static VALUE
+dcop_interfaces(VALUE self)
+{
+ VALUE dcopObject = rb_funcall(kde_module, rb_intern("createDCOPObject"), 1, self);
+ return rb_funcall(dcopObject, rb_intern("interfaces"), 0);
+}
+
+static VALUE
+dcop_connect_signal(VALUE self, VALUE sender, VALUE senderObj, VALUE signal, VALUE slot, VALUE volatile_connect)
+{
+ VALUE dcopObject = rb_funcall(kde_module, rb_intern("createDCOPObject"), 1, self);
+ return rb_funcall(dcopObject, rb_intern("connectDCOPSignal"), 5, sender, senderObj, signal, slot, volatile_connect);
+}
+
+static VALUE
+dcop_disconnect_signal(VALUE self, VALUE sender, VALUE senderObj, VALUE signal, VALUE slot)
+{
+ VALUE dcopObject = rb_funcall(kde_module, rb_intern("createDCOPObject"), 1, self);
+ return rb_funcall(dcopObject, rb_intern("disconnectDCOPSignal"), 4, sender, senderObj, signal, slot);
+}
+
+static VALUE
+dcop_process(VALUE /*self*/, VALUE target, VALUE slotname, VALUE args, VALUE data, VALUE replyTypeName, VALUE replyType, VALUE replyData)
+{
+ smokeruby_object *o = value_obj_info(data);
+ if (o == 0 || o->ptr == 0) {
+ return Qfalse;
+ }
+ QByteArray * dataArray = (QByteArray*) o->ptr;
+
+ o = value_obj_info(replyData);
+ if (o == 0 || o->ptr == 0) {
+ return Qfalse;
+ }
+ QByteArray * replyArray = (QByteArray*) o->ptr;
+
+ InvokeDCOPSlot dcopSlot(target, rb_intern(StringValuePtr(slotname)), args, *dataArray, replyTypeName, replyType, *replyArray);
+ dcopSlot.next();
+
+ return Qtrue;
+}
+
+static VALUE
+dcop_call(int argc, VALUE * argv, VALUE /*self*/)
+{
+ QCString fun(StringValuePtr(argv[1]));
+ VALUE args = argv[2];
+ bool useEventLoop = (argv[argc-2] == Qtrue ? true : false);
+ int timeout = NUM2INT(argv[argc-1]);
+
+ DCOPCall dcopCall(argv[0], fun, argc-5, argv+3, args, useEventLoop, timeout);
+ dcopCall.next();
+
+ return *(dcopCall.var());
+}
+
+static VALUE
+dcop_send(int argc, VALUE * argv, VALUE /*self*/)
+{
+ QCString fun(StringValuePtr(argv[1]));
+ VALUE args = argv[2];
+ VALUE result = Qnil;
+
+ DCOPSend dcopSend(argv[0], fun, argc-3, argv+3, args, &result);
+ dcopSend.next();
+
+ return result;
+}
+
+static VALUE
+new_kde(int argc, VALUE * argv, VALUE klass)
+{
+ VALUE instance = new_qt(argc, argv, klass);
+
+ if (rb_funcall(kde_module, rb_intern("hasDCOPSignals"), 1, klass) == Qtrue) {
+ VALUE signalNames = rb_funcall(kde_module, rb_intern("getDCOPSignalNames"), 1, klass);
+ for (long index = 0; index < RARRAY(signalNames)->len; index++) {
+ VALUE signal = rb_ary_entry(signalNames, index);
+ rb_define_method(klass, StringValuePtr(signal), (VALUE (*) (...)) k_dcop_signal, -1);
+ }
+ }
+
+ if ( rb_funcall(kde_module, rb_intern("hasDCOPSlots"), 1, klass) == Qtrue
+ || rb_funcall(kde_module, rb_intern("hasDCOPSignals"), 1, klass) == Qtrue )
+ {
+ VALUE dcop_object = rb_funcall(kde_module, rb_intern("createDCOPObject"), 1, instance);
+ if (dcop_object != Qnil) {
+ rb_define_method(klass, "interfaces", (VALUE (*) (...)) dcop_interfaces, 0);
+ rb_define_method(klass, "functions", (VALUE (*) (...)) dcop_functions, 0);
+ rb_define_method(klass, "connectDCOPSignal", (VALUE (*) (...)) dcop_connect_signal, 5);
+ rb_define_method(klass, "disconnectDCOPSignal", (VALUE (*) (...)) dcop_disconnect_signal, 4);
+ }
+ }
+
+ return instance;
+}
+
+#if KDE_VERSION >= 0x030200
+
+static VALUE
+kconfigskeletonitem_immutable(VALUE self)
+{
+ smokeruby_object *o = value_obj_info(self);
+ KConfigSkeletonItem * item = (KConfigSkeletonItem *) o->ptr;
+ return item->isImmutable() ? Qtrue : Qfalse;
+}
+
+static VALUE
+config_additem(int argc, VALUE * argv, VALUE self)
+{
+ smokeruby_object *o = value_obj_info(self);
+ KConfigSkeleton * config = (KConfigSkeleton *) o->ptr;
+
+ if (argc < 1 || argc > 2) {
+ rb_raise(rb_eArgError, "wrong number of arguments(%d for 2)\n", argc);
+ }
+
+ if (TYPE(argv[0]) != T_DATA) {
+ rb_raise(rb_eArgError, "wrong argument type, expected KDE::ConfigSkeletonItem\n", argc);
+ }
+
+ smokeruby_object *c = value_obj_info(argv[0]);
+ KConfigSkeletonItem * item = (KConfigSkeletonItem *) c->ptr;
+
+ if (argc == 1) {
+ config->addItem(item);
+ } else {
+ config->addItem(item, QString(StringValuePtr(argv[1])));
+ }
+
+ return self;
+}
+
+#endif
+
+static VALUE
+konsole_part_startprogram(VALUE self, VALUE value_program, VALUE value_args)
+{
+ smokeruby_object * o = value_obj_info(self);
+ TerminalInterface * t = static_cast<TerminalInterface*>(((KParts::ReadOnlyPart*) o->ptr)->qt_cast("TerminalInterface"));
+
+ QStrList *args = new QStrList;
+
+ if (value_args != Qnil) {
+ for (long i = 0; i < RARRAY(value_args)->len; i++) {
+ VALUE item = rb_ary_entry(value_args, i);
+ args->append(QString::fromLatin1(StringValuePtr(item), RSTRING(item)->len));
+ }
+ }
+
+ t->startProgram(QString::fromLatin1(StringValuePtr(value_program)), args);
+ return self;
+}
+
+static VALUE
+konsole_part_showshellindir(VALUE self, VALUE value_dir)
+{
+ smokeruby_object * o = value_obj_info(self);
+ TerminalInterface * t = static_cast<TerminalInterface*>(((KParts::ReadOnlyPart*) o->ptr)->qt_cast("TerminalInterface"));
+ t->showShellInDir(StringValuePtr(value_dir));
+ return self;
+}
+
+static VALUE
+konsole_part_sendinput(VALUE self, VALUE value_text)
+{
+ smokeruby_object * o = value_obj_info(self);
+ TerminalInterface * t = static_cast<TerminalInterface*>(((KParts::ReadOnlyPart*) o->ptr)->qt_cast("TerminalInterface"));
+ t->sendInput(StringValuePtr(value_text));
+ return self;
+}
+
+#if KDE_VERSION >= 0x030500
+static VALUE
+konsole_part_setautostartshell(VALUE self, VALUE enabled)
+{
+ smokeruby_object * o = value_obj_info(self);
+ ExtTerminalInterface * t = static_cast<ExtTerminalInterface*>(((KParts::ReadOnlyPart*) o->ptr)->qt_cast("ExtTerminalInterface"));
+ t->setAutoStartShell(enabled == Qtrue);
+ return self;
+}
+
+static VALUE
+konsole_part_setautodestroy(VALUE self, VALUE enabled)
+{
+ smokeruby_object * o = value_obj_info(self);
+ ExtTerminalInterface * t = static_cast<ExtTerminalInterface*>(((KParts::ReadOnlyPart*) o->ptr)->qt_cast("ExtTerminalInterface"));
+ t->setAutoDestroy(enabled == Qtrue);
+ return self;
+}
+#endif
+
+void
+Init_korundum()
+{
+ if (qt_internal_module != Qnil) {
+ rb_fatal("require 'Korundum' must not follow require 'Qt'\n");
+ return;
+ }
+
+ set_new_kde(new_kde);
+#if KDE_VERSION >= 0x030200
+ set_kconfigskeletonitem_immutable(kconfigskeletonitem_immutable);
+#endif
+ set_kde_resolve_classname(kde_resolve_classname);
+
+ // The Qt extension is linked against libsmokeqt.so, but Korundum links against
+ // libsmokekde.so only. Specifying both a 'require Qt' and a 'require Korundum',
+ // would give a link error (see the rb_fatal() error above).
+ // So call the Init_qtruby() initialization function explicitely, not via 'require Qt'
+ // (Qt.o is linked into libqtruby.so, as well as the Qt.so extension).
+ Init_qtruby();
+ install_handlers(KDE_handlers);
+
+ kde_internal_module = rb_define_module_under(kde_module, "Internal");
+ rb_define_singleton_method(kde_module, "dcop_process", (VALUE (*) (...)) dcop_process, 7);
+ rb_define_singleton_method(kde_module, "dcop_call", (VALUE (*) (...)) dcop_call, -1);
+ rb_define_singleton_method(kde_module, "dcop_send", (VALUE (*) (...)) dcop_send, -1);
+
+#if KDE_VERSION >= 0x030200
+ rb_define_method(kconfigskeleton_class, "addItem", (VALUE (*) (...)) config_additem, -1);
+#endif
+
+ rb_define_method(konsole_part_class, "startProgram", (VALUE (*) (...)) konsole_part_startprogram, 2);
+ rb_define_method(konsole_part_class, "showShellInDir", (VALUE (*) (...)) konsole_part_showshellindir, 1);
+ rb_define_method(konsole_part_class, "sendInput", (VALUE (*) (...)) konsole_part_sendinput, 1);
+#if KDE_VERSION >= 0x030500
+ rb_define_method(konsole_part_class, "setAutoStartShell", (VALUE (*) (...)) konsole_part_setautostartshell, 1);
+ rb_define_method(konsole_part_class, "autoStartShell=", (VALUE (*) (...)) konsole_part_setautostartshell, 1);
+ rb_define_method(konsole_part_class, "setAutoDestroy", (VALUE (*) (...)) konsole_part_setautodestroy, 1);
+ rb_define_method(konsole_part_class, "autoDestroy=", (VALUE (*) (...)) konsole_part_setautodestroy, 1);
+#endif
+
+ rb_require("KDE/korundum.rb");
+}
+
+};
diff --git a/korundum/rubylib/korundum/Makefile.am b/korundum/rubylib/korundum/Makefile.am
new file mode 100644
index 00000000..c135f4e9
--- /dev/null
+++ b/korundum/rubylib/korundum/Makefile.am
@@ -0,0 +1,10 @@
+INCLUDES = -I$(top_srcdir)/smoke -I$(top_srcdir)/qtruby/rubylib/qtruby $(all_includes) -I$(RUBY_ARCHDIR)
+
+rubylibdir = $(RUBY_SITEARCHDIR)
+rubylib_LTLIBRARIES = korundum.la
+korundum_la_LDFLAGS = -module $(all_libraries) -version-info 0:0:0
+korundum_la_METASOURCES = AUTO
+korundum_la_SOURCES = Korundum.cpp kdehandlers.cpp
+korundum_la_LIBADD = $(LIB_KDE) $(top_builddir)/smoke/kde/libsmokekde.la $(top_builddir)/qtruby/rubylib/qtruby/libqtrubyinternal.la
+
+SUBDIRS = lib
diff --git a/korundum/rubylib/korundum/configure.in.in b/korundum/rubylib/korundum/configure.in.in
new file mode 100644
index 00000000..de265e6d
--- /dev/null
+++ b/korundum/rubylib/korundum/configure.in.in
@@ -0,0 +1,15 @@
+AC_CHECK_PROG(RUBY, ruby, ruby)
+
+if test -z "$RUBY"; then
+ DO_NOT_COMPILE="$DO_NOT_COMPILE korundum"
+else
+ AC_MSG_CHECKING(for ruby dirs)
+ RUBY_ARCHDIR=`ruby -r rbconfig -e 'printf("%s",Config::CONFIG@<:@"archdir"@:>@)'`
+ RUBY_SITEARCHDIR=`ruby -r rbconfig -e 'printf("%s",Config::CONFIG@<:@"sitearchdir"@:>@)'`
+ RUBY_SITEDIR=`ruby -r rbconfig -e 'printf("%s",Config::CONFIG@<:@"sitelibdir"@:>@)'`
+ AC_MSG_RESULT([archdir $RUBY_ARCHDIR, sitearchdir $RUBY_SITEARCHDIR, sitedir $RUBY_SITEDIR])
+ AC_SUBST(RUBY_ARCHDIR)
+ AC_SUBST(RUBY_SITEARCHDIR)
+ AC_SUBST(RUBY_SITEDIR)
+fi
+
diff --git a/korundum/rubylib/korundum/kdehandlers.cpp b/korundum/rubylib/korundum/kdehandlers.cpp
new file mode 100644
index 00000000..4d8d5741
--- /dev/null
+++ b/korundum/rubylib/korundum/kdehandlers.cpp
@@ -0,0 +1,1428 @@
+/***************************************************************************
+ kdehandlers.cpp - KDE specific marshallers
+ -------------------
+ begin : Sun Sep 28 2003
+ copyright : (C) 2003 by Richard Dale
+ email : Richard_Dale@tipitina.demon.co.uk
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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 <qtruby.h>
+#include <smokeruby.h>
+
+#include <kdeversion.h>
+#include <dcopclient.h>
+#include <dcopobject.h>
+#include <dcopref.h>
+#include <qptrlist.h>
+#include <ktrader.h>
+#include <kservicegroup.h>
+#include <kservice.h>
+#include <ksycocatype.h>
+#include <kmainwindow.h>
+#include <kfile.h>
+#include <kfileview.h>
+#include <kurl.h>
+#include <kcmdlineargs.h>
+#include <kaction.h>
+#include <kdockwidget.h>
+#include <kfiletreebranch.h>
+#include <kfiletreeviewitem.h>
+#include <khtml_part.h>
+#include <kparts/plugin.h>
+#include <kuserprofile.h>
+#include <kaboutdata.h>
+#include <karchive.h>
+#if KDE_VERSION >= 0x030200
+#include <kconfigskeleton.h>
+#include <kplugininfo.h>
+#include <kmountpoint.h>
+#endif
+#include <kio/jobclasses.h>
+#include <dom/dom_node.h>
+#include <dom/dom_element.h>
+#include <dom/dom_string.h>
+#include <dom/html_element.h>
+
+extern "C" {
+extern VALUE set_obj_info(const char * className, smokeruby_object * o);
+};
+
+extern bool isDerivedFromByName(Smoke *smoke, const char *className, const char *baseClassName);
+
+extern "C" {
+/*
+ * Given an approximate classname and a kde instance, try to improve the resolution of the name
+ * by using the various KDE rtti mechanisms
+ */
+const char *
+kde_resolve_classname(Smoke * smoke, int classId, void * ptr)
+{
+ if (isDerivedFromByName(smoke, smoke->classes[classId].className, "KArchiveEntry")) {
+ KArchiveEntry * entry = (KArchiveEntry *) smoke->cast(ptr, classId, smoke->idClass("KArchiveEntry"));
+ if (entry->isDirectory()) {
+ return "KDE::ArchiveDirectory";
+ } else {
+ return "KDE::ArchiveFile";
+ }
+ } else if (strcmp(smoke->classes[classId].className, "DOM::Node") == 0) {
+ DOM::Node * node = (DOM::Node *) smoke->cast(ptr, classId, smoke->idClass("DOM::Node"));
+ switch (node->nodeType()) {
+ case DOM::Node::ELEMENT_NODE:
+ if (((DOM::Element*)node)->isHTMLElement()) {
+ return "DOM::HTMLElement";
+ } else {
+ return "DOM::Element";
+ }
+ case DOM::Node::ATTRIBUTE_NODE:
+ return "DOM::Attr";
+ case DOM::Node::TEXT_NODE:
+ return "DOM::Text";
+ case DOM::Node::CDATA_SECTION_NODE:
+ return "DOM::CDATASection";
+ case DOM::Node::ENTITY_REFERENCE_NODE:
+ return "DOM::EntityReference";
+ case DOM::Node::ENTITY_NODE:
+ return "DOM::Entity";
+ case DOM::Node::PROCESSING_INSTRUCTION_NODE:
+ return "DOM::ProcessingInstruction";
+ case DOM::Node::COMMENT_NODE:
+ return "DOM::Comment";
+ case DOM::Node::DOCUMENT_NODE:
+ return "DOM::Document";
+ case DOM::Node::DOCUMENT_TYPE_NODE:
+ return "DOM::DocumentType";
+ case DOM::Node::DOCUMENT_FRAGMENT_NODE:
+ return "DOM::DocumentFragment";
+ case DOM::Node::NOTATION_NODE:
+ return "DOM::Notation";
+ }
+ }
+
+ return smoke->binding->className(classId);
+}
+
+};
+
+void marshall_QCStringList(Marshall *m) {
+ switch(m->action()) {
+ case Marshall::FromVALUE:
+ {
+ VALUE list = *(m->var());
+ if (TYPE(list) != T_ARRAY) {
+ m->item().s_voidp = 0;
+ break;
+ }
+
+ int count = RARRAY(list)->len;
+ QCStringList *stringlist = new QCStringList;
+
+ for(long i = 0; i < count; i++) {
+ VALUE item = rb_ary_entry(list, i);
+ if(TYPE(item) != T_STRING) {
+ stringlist->append(QCString());
+ continue;
+ }
+ stringlist->append(QCString(StringValuePtr(item), RSTRING(item)->len + 1));
+ }
+
+ m->item().s_voidp = stringlist;
+ m->next();
+
+ if(m->cleanup()) {
+ rb_ary_clear(list);
+ for(QCStringList::Iterator it = stringlist->begin(); it != stringlist->end(); ++it)
+ rb_ary_push(list, rb_str_new2(static_cast<const char *>(*it)));
+ delete stringlist;
+ }
+ break;
+ }
+ case Marshall::ToVALUE:
+ {
+ QCStringList *stringlist = static_cast<QCStringList *>(m->item().s_voidp);
+ if(!stringlist) {
+ *(m->var()) = Qnil;
+ break;
+ }
+
+ VALUE av = rb_ary_new();
+ for(QCStringList::Iterator it = stringlist->begin(); it != stringlist->end(); ++it) {
+ VALUE rv = rb_str_new2(static_cast<const char *>((*it)));
+ rb_ary_push(av, rv);
+ }
+
+ if(m->cleanup())
+ delete stringlist;
+
+ *(m->var()) = av;
+ }
+ break;
+ default:
+ m->unsupported();
+ break;
+ }
+}
+
+#if defined (__i386__) && defined (__GNUC__) && __GNUC__ >= 2
+# define BREAKPOINT { __asm__ __volatile__ ("int $03"); }
+#else
+# define BREAKPOINT { fprintf(stderr, "hit ctrl-c\n"); int b = 0; while (b == 0) { ; } }
+#endif
+
+void marshall_KCmdLineOptions(Marshall *m) {
+ switch(m->action()) {
+ case Marshall::FromVALUE:
+ {
+ VALUE optionslist = *(m->var());
+ if (optionslist == Qnil
+ || TYPE(optionslist) != T_ARRAY
+ || RARRAY(optionslist)->len == 0 )
+ {
+ m->item().s_voidp = 0;
+ break;
+ }
+
+ // Allocate 'length + 1' entries, to include an all NULLs last entry
+ KCmdLineOptions *cmdLineOptions = (KCmdLineOptions *) calloc( RARRAY(optionslist)->len + 1,
+ sizeof(struct KCmdLineOptions) );
+
+ VALUE options;
+ long i;
+ for(i = 0; i < RARRAY(optionslist)->len; i++) {
+ options = rb_ary_entry(optionslist, i);
+ VALUE temp = rb_ary_entry(options, 0);
+ cmdLineOptions[i].name = StringValuePtr(temp);
+ temp = rb_ary_entry(options, 1);
+ cmdLineOptions[i].description = StringValuePtr(temp);
+ temp = rb_ary_entry(options, 2);
+ cmdLineOptions[i].def = StringValuePtr(temp);
+ }
+ cmdLineOptions[i].name = 0;
+ cmdLineOptions[i].description = 0;
+ cmdLineOptions[i].def = 0;
+
+
+ m->item().s_voidp = cmdLineOptions;
+ m->next();
+ /*
+ if(m->cleanup()) {
+ rb_ary_clear(optionslist);
+ for(i = 0; cmdLineOptions[i].name; i++)
+ options = rb_ary_new();
+ rb_ary_push(options, rb_str_new2(cmdLineOptions[i].name));
+ rb_ary_push(options, rb_str_new2(cmdLineOptions[i].description));
+ rb_ary_push(options, rb_str_new2(cmdLineOptions[i].def));
+ rb_ary_push(optionslist, options);
+ }
+ */
+ }
+ break;
+ case Marshall::ToVALUE:
+ {
+ }
+ break;
+ default:
+ m->unsupported();
+ break;
+ }
+}
+
+void marshall_WIdList(Marshall *m) {
+ switch(m->action()) {
+ case Marshall::FromVALUE:
+ {
+ VALUE list = *(m->var());
+ if (TYPE(list) != T_ARRAY) {
+ m->item().s_voidp = 0;
+ break;
+ }
+ int count = RARRAY(list)->len;
+ QValueList<WId> *valuelist = new QValueList<WId>;
+ long i;
+ for(i = 0; i < count; i++) {
+ VALUE item = rb_ary_entry(list, i);
+ if(TYPE(item) != T_FIXNUM && TYPE(item) != T_BIGNUM) {
+ valuelist->append(0);
+ continue;
+ }
+ valuelist->append(NUM2LONG(item));
+ }
+
+ m->item().s_voidp = valuelist;
+ m->next();
+
+ if (!m->type().isConst()) {
+ rb_ary_clear(list);
+ for(QValueListIterator<WId> it = valuelist->begin();
+ it != valuelist->end();
+ ++it)
+ rb_ary_push(list, LONG2NUM((int)*it));
+ }
+
+ if (m->cleanup()) {
+ delete valuelist;
+ }
+ }
+ break;
+ case Marshall::ToVALUE:
+ {
+ QValueList<WId> *valuelist = (QValueList<WId>*)m->item().s_voidp;
+ if(!valuelist) {
+ *(m->var()) = Qnil;
+ break;
+ }
+
+ VALUE av = rb_ary_new();
+
+ for(QValueListIterator<WId> it = valuelist->begin();
+ it != valuelist->end();
+ ++it)
+ rb_ary_push(av, LONG2NUM(*it));
+
+ *(m->var()) = av;
+
+ if(m->cleanup())
+ delete valuelist;
+ }
+ break;
+ default:
+ m->unsupported();
+ break;
+ }
+}
+
+void marshall_KMimeTypeList(Marshall *m) {
+ switch(m->action()) {
+ case Marshall::FromVALUE:
+ {
+ }
+ break;
+ case Marshall::ToVALUE:
+ {
+ KMimeType::List *offerList = (KMimeType::List*)m->item().s_voidp;
+ if(!offerList) {
+ *(m->var()) = Qnil;
+ break;
+ }
+
+ VALUE av = rb_ary_new();
+
+ for(KMimeType::List::Iterator it = offerList->begin();
+ it != offerList->end();
+ ++it) {
+ KMimeType * item = new KMimeType (*(KMimeType*)((KMimeType::Ptr)(*it)).data());
+
+ VALUE obj = getPointerObject(item);
+ if(obj == Qnil) {
+ smokeruby_object * o = ALLOC(smokeruby_object);
+ o->smoke = m->smoke();
+ o->classId = m->smoke()->idClass("KMimeType");
+ o->ptr = item;
+ o->allocated = true;
+ obj = set_obj_info("KDE::MimeType", o);
+ }
+ rb_ary_push(av, obj);
+ }
+
+ *(m->var()) = av;
+
+ if(m->cleanup())
+ delete offerList;
+ }
+ break;
+ default:
+ m->unsupported();
+ break;
+ }
+}
+
+void marshall_KMimeTypePtr(Marshall *m) {
+ switch(m->action()) {
+ case Marshall::FromVALUE:
+ {
+ }
+ break;
+ case Marshall::ToVALUE:
+ {
+ KMimeType::Ptr ptr(*(KMimeType::Ptr*)m->item().s_voidp);
+ if(ptr == 0) {
+ *(m->var()) = Qnil;
+ break;
+ }
+ KMimeType * mimeType = new KMimeType(*(KMimeType*)ptr);
+
+ VALUE obj = getPointerObject(mimeType);
+ if(obj == Qnil) {
+ smokeruby_object * o = ALLOC(smokeruby_object);
+ o->smoke = m->smoke();
+ o->classId = m->smoke()->idClass("KMimeType");
+ o->ptr = mimeType;
+ o->allocated = true;
+ obj = set_obj_info("KDE::MimeType", o);
+ }
+
+ *(m->var()) = obj;
+
+ if(m->cleanup())
+ ;
+ }
+ break;
+ default:
+ m->unsupported();
+ break;
+ }
+}
+
+void marshall_KServicePtr(Marshall *m) {
+ switch(m->action()) {
+ case Marshall::FromVALUE:
+ {
+ }
+ break;
+ case Marshall::ToVALUE:
+ {
+ KSharedPtr<KService> *ptr = new KSharedPtr<KService>(*(KSharedPtr<KService>*)m->item().s_voidp);
+ if(ptr == 0) {
+ *(m->var()) = Qnil;
+ break;
+ }
+ KService * service = ptr->data();
+
+ VALUE obj = getPointerObject(service);
+ if(obj == Qnil) {
+ smokeruby_object * o = ALLOC(smokeruby_object);
+ o->smoke = m->smoke();
+ o->classId = m->smoke()->idClass("KService");
+ o->ptr = service;
+ o->allocated = true;
+ obj = set_obj_info("KDE::Service", o);
+ }
+
+ *(m->var()) = obj;
+
+ if(m->cleanup())
+ ;
+ }
+ break;
+ default:
+ m->unsupported();
+ break;
+ }
+}
+
+void marshall_KServiceList(Marshall *m) {
+ switch(m->action()) {
+ case Marshall::FromVALUE:
+ {
+ }
+ break;
+ case Marshall::ToVALUE:
+ {
+ KService::List *offerList = (KService::List*)m->item().s_voidp;
+ if(!offerList) {
+ *(m->var()) = Qnil;
+ break;
+ }
+
+ VALUE av = rb_ary_new();
+
+ for(KService::List::Iterator it = offerList->begin();
+ it != offerList->end();
+ ++it) {
+ KSharedPtr<KService> *ptr = new KSharedPtr<KService>(*it);
+ KService * currentOffer = ptr->data();
+
+ VALUE obj = getPointerObject(currentOffer);
+ if(obj == Qnil) {
+ smokeruby_object * o = ALLOC(smokeruby_object);
+ o->smoke = m->smoke();
+ o->classId = m->smoke()->idClass("KService");
+ o->ptr = currentOffer;
+ o->allocated = false;
+ obj = set_obj_info("KDE::Service", o);
+ }
+ rb_ary_push(av, obj);
+ }
+
+ *(m->var()) = av;
+
+ if(m->cleanup())
+ delete offerList;
+ }
+ break;
+ default:
+ m->unsupported();
+ break;
+ }
+}
+
+void marshall_KServiceGroupPtr(Marshall *m) {
+ switch(m->action()) {
+ case Marshall::FromVALUE:
+ {
+ }
+ break;
+ case Marshall::ToVALUE:
+ {
+ KServiceGroup::Ptr ptr(*(KServiceGroup::Ptr*)m->item().s_voidp);
+ if(ptr == 0) {
+ *(m->var()) = Qnil;
+ break;
+ }
+ KServiceGroup * serviceGroup = new KServiceGroup(*(KServiceGroup*)ptr);
+
+ VALUE obj = getPointerObject(serviceGroup);
+ if(obj == Qnil) {
+ smokeruby_object * o = ALLOC(smokeruby_object);
+ o->smoke = m->smoke();
+ o->classId = m->smoke()->idClass("KServiceGroup");
+ o->ptr = serviceGroup;
+ o->allocated = true;
+ obj = set_obj_info("KDE::ServiceGroup", o);
+ }
+
+ *(m->var()) = obj;
+
+ if(m->cleanup())
+ ;
+ }
+ break;
+ default:
+ m->unsupported();
+ break;
+ }
+}
+
+void marshall_KServiceTypeList(Marshall *m) {
+ switch(m->action()) {
+ case Marshall::FromVALUE:
+ {
+ }
+ break;
+ case Marshall::ToVALUE:
+ {
+ KServiceType::List *offerList = (KServiceType::List*)m->item().s_voidp;
+ if(!offerList) {
+ *(m->var()) = Qnil;
+ break;
+ }
+
+ VALUE av = rb_ary_new();
+
+ for(KServiceType::List::Iterator it = offerList->begin();
+ it != offerList->end();
+ ++it) {
+ KServiceType * currentOffer = new KServiceType(*((KServiceType*)*it));
+
+ VALUE obj = getPointerObject(currentOffer);
+ if(obj == Qnil) {
+ smokeruby_object * o = ALLOC(smokeruby_object);
+ o->smoke = m->smoke();
+ o->classId = m->smoke()->idClass("KServiceType");
+ o->ptr = currentOffer;
+ o->allocated = true;
+ obj = set_obj_info("KDE::ServiceType", o);
+ }
+ rb_ary_push(av, obj);
+ }
+
+ *(m->var()) = av;
+
+ if(m->cleanup())
+ delete offerList;
+ }
+ break;
+ default:
+ m->unsupported();
+ break;
+ }
+}
+
+void marshall_KServiceGroupList(Marshall *m) {
+ switch(m->action()) {
+ case Marshall::FromVALUE:
+ {
+ }
+ break;
+ case Marshall::ToVALUE:
+ {
+ KServiceGroup::List *offerList = (KServiceGroup::List*)m->item().s_voidp;
+ if(!offerList) {
+ *(m->var()) = Qnil;
+ break;
+ }
+
+ VALUE av = rb_ary_new();
+
+ for(KServiceGroup::List::ConstIterator it = offerList->begin();
+ it != offerList->end();
+ ++it) {
+ KSycocaEntry *p = (*it);
+ VALUE obj = Qnil;
+ if (p->isType(KST_KService)) {
+ KService *s = static_cast<KService *>(p);
+ obj = getPointerObject(s);
+ if(obj == Qnil) {
+ smokeruby_object * o = ALLOC(smokeruby_object);
+ o->smoke = m->smoke();
+ o->classId = m->smoke()->idClass("KService");
+ o->ptr = s;
+ o->allocated = true;
+ obj = set_obj_info("KDE::Service", o);
+ }
+ } else if (p->isType(KST_KServiceGroup)) {
+ KServiceGroup *g = static_cast<KServiceGroup *>(p);
+ obj = getPointerObject(g);
+ if(obj == Qnil) {
+ smokeruby_object * o = ALLOC(smokeruby_object);
+ o->smoke = m->smoke();
+ o->classId = m->smoke()->idClass("KServiceGroup");
+ o->ptr = g;
+ o->allocated = true;
+ obj = set_obj_info("KDE::ServiceGroup", o);
+ }
+ }
+
+ rb_ary_push(av, obj);
+ }
+
+ *(m->var()) = av;
+
+ if(m->cleanup())
+ delete offerList;
+ }
+ break;
+ default:
+ m->unsupported();
+ break;
+ }
+}
+
+#if KDE_VERSION >= 0x030200
+void marshall_KMountPointList(Marshall *m) {
+ switch(m->action()) {
+ case Marshall::FromVALUE:
+ {
+ }
+ break;
+ case Marshall::ToVALUE:
+ {
+ KMountPoint::List *list = (KMountPoint::List*)m->item().s_voidp;
+ if(!list) {
+ *(m->var()) = Qnil;
+ break;
+ }
+
+ VALUE av = rb_ary_new();
+
+ for(KMountPoint::List::Iterator it = list->begin();
+ it != list->end();
+ ++it) {
+ KMountPoint * item = new KMountPoint(*((KMountPoint*)*it));
+
+ VALUE obj = getPointerObject(item);
+ if(obj == Qnil) {
+ smokeruby_object * o = ALLOC(smokeruby_object);
+ o->smoke = m->smoke();
+ o->classId = m->smoke()->idClass("KMountPoint");
+ o->ptr = item;
+ o->allocated = true;
+ obj = set_obj_info("KDE::MountPoint", o);
+ }
+ rb_ary_push(av, obj);
+ }
+
+ *(m->var()) = av;
+
+ if(m->cleanup())
+ delete list;
+ }
+ break;
+ default:
+ m->unsupported();
+ break;
+ }
+}
+
+void marshall_KPluginInfoList(Marshall *m) {
+ switch(m->action()) {
+ case Marshall::FromVALUE:
+ {
+ }
+ break;
+ case Marshall::ToVALUE:
+ {
+ KPluginInfo::List *valuelist = (KPluginInfo::List*)m->item().s_voidp;
+ if(!valuelist) {
+ *(m->var()) = Qnil;
+ break;
+ }
+
+ VALUE av = rb_ary_new();
+
+ int ix = m->smoke()->idClass("KPluginInfo");
+ const char * className = m->smoke()->binding->className(ix);
+
+ for(KPluginInfo::List::Iterator it = valuelist->begin();
+ it != valuelist->end();
+ ++it) {
+ void *p = (*it);
+
+ if(m->item().s_voidp == 0) {
+ *(m->var()) = Qnil;
+ break;
+ }
+
+ VALUE obj = getPointerObject(p);
+ if(obj == Qnil) {
+ smokeruby_object * o = ALLOC(smokeruby_object);
+ o->smoke = m->smoke();
+ o->classId = o->smoke->idClass("KPluginInfo");
+ o->ptr = p;
+ o->allocated = false;
+ obj = set_obj_info(className, o);
+ }
+ rb_ary_push(av, obj);
+ }
+
+ if(m->cleanup())
+ delete valuelist;
+ else
+ *(m->var()) = av;
+ }
+ break;
+ default:
+ m->unsupported();
+ break;
+ }
+}
+#endif
+
+void marshall_KActionPtrList(Marshall *m) {
+ switch(m->action()) {
+ case Marshall::FromVALUE:
+ {
+ }
+ break;
+ case Marshall::ToVALUE:
+ {
+ KActionPtrList *valuelist = (KActionPtrList*)m->item().s_voidp;
+ if (!valuelist) {
+ *(m->var()) = Qnil;
+ break;
+ }
+
+ VALUE av = rb_ary_new();
+
+ int ix = m->smoke()->idClass("KAction");
+ const char * className = m->smoke()->binding->className(ix);
+
+ for ( KActionPtrList::Iterator it = valuelist->begin();
+ it != valuelist->end();
+ ++it )
+ {
+ void *p = (*it);
+
+ if (m->item().s_voidp == 0) {
+ *(m->var()) = Qnil;
+ break;
+ }
+
+ VALUE obj = getPointerObject(p);
+ if (obj == Qnil) {
+ smokeruby_object * o = ALLOC(smokeruby_object);
+ o->smoke = m->smoke();
+ o->classId = o->smoke->idClass("KAction");
+ o->ptr = p;
+ o->allocated = false;
+ obj = set_obj_info(className, o);
+ }
+ rb_ary_push(av, obj);
+ }
+
+ if (m->cleanup())
+ delete valuelist;
+ else
+ *(m->var()) = av;
+ }
+ break;
+ default:
+ m->unsupported();
+ break;
+ }
+}
+
+void marshall_KTraderOfferList(Marshall *m) {
+ switch(m->action()) {
+ case Marshall::FromVALUE:
+ {
+ }
+ break;
+ case Marshall::ToVALUE:
+ {
+ KTrader::OfferList *offerList = (KTrader::OfferList*)m->item().s_voidp;
+ if(!offerList) {
+ *(m->var()) = Qnil;
+ break;
+ }
+
+ VALUE av = rb_ary_new();
+
+ for(KTrader::OfferList::Iterator it = offerList->begin();
+ it != offerList->end();
+ ++it) {
+ KSharedPtr<KService> *ptr = new KSharedPtr<KService>(*it);
+ KService * currentOffer = ptr->data();
+
+ VALUE obj = getPointerObject(currentOffer);
+ if(obj == Qnil) {
+ smokeruby_object * o = ALLOC(smokeruby_object);
+ o->smoke = m->smoke();
+ o->classId = m->smoke()->idClass("KService");
+ o->ptr = currentOffer;
+ o->allocated = false;
+ obj = set_obj_info("KDE::Service", o);
+ }
+ rb_ary_push(av, obj);
+ }
+
+ *(m->var()) = av;
+
+ if(m->cleanup())
+ delete offerList;
+ }
+ break;
+ default:
+ m->unsupported();
+ break;
+ }
+}
+
+void marshall_KURLList(Marshall *m) {
+ switch(m->action()) {
+ case Marshall::FromVALUE:
+ {
+ VALUE list = *(m->var());
+ if (TYPE(list) != T_ARRAY) {
+ m->item().s_voidp = 0;
+ break;
+ }
+ int count = RARRAY(list)->len;
+ KURL::List *kurllist = new KURL::List;
+ long i;
+ for(i = 0; i < count; i++) {
+ VALUE item = rb_ary_entry(list, i);
+ // TODO do type checking!
+ smokeruby_object *o = value_obj_info(item);
+ if(!o || !o->ptr)
+ continue;
+ void *ptr = o->ptr;
+ ptr = o->smoke->cast(
+ ptr, // pointer
+ o->classId, // from
+ o->smoke->idClass("KURL") // to
+ );
+ kurllist->append((KURL&)*(KURL*)ptr);
+ }
+
+ m->item().s_voidp = kurllist;
+ m->next();
+
+ rb_ary_clear(list);
+ int ix = m->smoke()->idClass("KURL");
+ const char * className = m->smoke()->binding->className(ix);
+ for ( KURL::List::Iterator it = kurllist->begin();
+ it != kurllist->end();
+ ++it )
+ {
+ void *p = new KURL(*it);
+ VALUE obj = getPointerObject(p);
+ if(obj == Qnil) {
+ smokeruby_object * o = ALLOC(smokeruby_object);
+ o->smoke = m->smoke();
+ o->classId = ix;
+ o->ptr = p;
+ o->allocated = true;
+ obj = set_obj_info(className, o);
+ }
+ rb_ary_push(list, obj);
+ }
+
+ if(m->cleanup()) {
+ delete kurllist;
+ }
+ }
+ break;
+ case Marshall::ToVALUE:
+ {
+ KURL::List *kurllist = (KURL::List*)m->item().s_voidp;
+ if(!kurllist) {
+ *(m->var()) = Qnil;
+ break;
+ }
+
+ VALUE av = rb_ary_new();
+
+ int ix = m->smoke()->idClass("KURL");
+ const char * className = m->smoke()->binding->className(ix);
+
+ for(KURL::List::Iterator it = kurllist->begin();
+ it != kurllist->end();
+ ++it) {
+ void *p = new KURL(*it);
+
+ VALUE obj = getPointerObject(p);
+ if(obj == Qnil) {
+ smokeruby_object * o = ALLOC(smokeruby_object);
+ o->smoke = m->smoke();
+ o->classId = ix;
+ o->ptr = p;
+ o->allocated = true;
+ obj = set_obj_info(className, o);
+ }
+ rb_ary_push(av, obj);
+ }
+
+ *(m->var()) = av;
+
+ if(m->cleanup()) {
+ delete kurllist;
+ }
+ }
+ break;
+ default:
+ m->unsupported();
+ break;
+ }
+}
+
+void marshall_UDSEntryList(Marshall *m) {
+ switch(m->action()) {
+ case Marshall::FromVALUE:
+ {
+ VALUE list = *(m->var());
+ if (TYPE(list) != T_ARRAY) {
+ m->item().s_voidp = 0;
+ break;
+ }
+
+ KIO::UDSEntryList *cpplist = new KIO::UDSEntryList;
+
+ for(long i = 0; i < RARRAY(list)->len; i++) {
+ VALUE item = rb_ary_entry(list, i);
+ KIO::UDSEntry *cppsublist = new KIO::UDSEntry;
+
+ for (int j = 0; j < RARRAY(item)->len; j++) {
+ VALUE subitem = rb_ary_entry(item, j);
+ smokeruby_object *o = value_obj_info(subitem);
+ if(!o || !o->ptr)
+ continue;
+ void *ptr = o->ptr;
+ ptr = o->smoke->cast(ptr, o->classId, o->smoke->idClass("KIO::UDSAtom"));
+ cppsublist->append(*(KIO::UDSAtom*)ptr);
+ }
+
+ cpplist->append(*cppsublist);
+ }
+
+ m->item().s_voidp = cpplist;
+ m->next();
+ }
+ break;
+ case Marshall::ToVALUE:
+ {
+ KIO::UDSEntryList *valuelist = (KIO::UDSEntryList*)m->item().s_voidp;
+ if (!valuelist) {
+ *(m->var()) = Qnil;
+ break;
+ }
+
+ VALUE av = rb_ary_new();
+
+ int ix = m->smoke()->idClass("KIO::UDSAtom");
+
+ for ( KIO::UDSEntryList::Iterator it = valuelist->begin();
+ it != valuelist->end();
+ ++it )
+ {
+ KIO::UDSEntry * udsentry = &(*it);
+ VALUE subav = rb_ary_new();
+
+ for ( KIO::UDSEntry::Iterator it = udsentry->begin();
+ it != udsentry->end();
+ ++it )
+ {
+ void * p = &(*it);
+ VALUE obj = getPointerObject(p);
+ if(obj == Qnil) {
+ smokeruby_object * o = ALLOC(smokeruby_object);
+ o->smoke = m->smoke();
+ o->classId = ix;
+ o->ptr = p;
+ o->allocated = false;
+ obj = set_obj_info("KIO::UDSAtom", o);
+ }
+
+ rb_ary_push(subav, obj);
+ }
+
+ rb_ary_push(av, subav);
+ }
+
+ *(m->var()) = av;
+ }
+ break;
+ default:
+ m->unsupported();
+ break;
+ }
+}
+
+
+// Some time saving magic from Alex Kellett here..
+template <class Item, class ItemList, const char *ItemSTR >
+void marshall_ItemList(Marshall *m) {
+ switch(m->action()) {
+ case Marshall::FromVALUE:
+ {
+ VALUE list = *(m->var());
+ if (TYPE(list) != T_ARRAY) {
+ m->item().s_voidp = 0;
+ break;
+ }
+ int count = RARRAY(list)->len;
+ ItemList *cpplist = new ItemList;
+ long i;
+ for(i = 0; i < count; i++) {
+ VALUE item = rb_ary_entry(list, i);
+ // TODO do type checking!
+ smokeruby_object *o = value_obj_info(item);
+ if(!o || !o->ptr)
+ continue;
+ void *ptr = o->ptr;
+ ptr = o->smoke->cast(
+ ptr, // pointer
+ o->classId, // from
+ o->smoke->idClass(ItemSTR) // to
+ );
+ cpplist->append((Item*)ptr);
+ }
+
+ m->item().s_voidp = cpplist;
+ m->next();
+
+ if(m->cleanup()) {
+ rb_ary_clear(list);
+ for( Item * it = cpplist->first();
+ it != 0;
+ it = cpplist->next()) {
+ VALUE obj = getPointerObject((void*)it);
+ rb_ary_push(list, obj);
+ }
+ delete cpplist;
+ }
+ }
+ break;
+ case Marshall::ToVALUE:
+ {
+ ItemList *valuelist = (ItemList*)m->item().s_voidp;
+ if(!valuelist) {
+ *(m->var()) = Qnil;
+ break;
+ }
+
+ VALUE av = rb_ary_new();
+
+ int ix = m->smoke()->idClass(ItemSTR);
+ const char * className = m->smoke()->binding->className(ix);
+
+ for(Item * it = valuelist->first();
+ it != 0;
+ it = valuelist->next()) {
+ void *p = it;
+
+ if(m->item().s_voidp == 0) {
+ *(m->var()) = Qnil;
+ break;
+ }
+
+ VALUE obj = getPointerObject(p);
+ if(obj == Qnil) {
+ smokeruby_object * o = ALLOC(smokeruby_object);
+ o->smoke = m->smoke();
+ o->classId = o->smoke->idClass(ItemSTR);
+ o->ptr = p;
+ o->allocated = false;
+ obj = set_obj_info(className, o);
+ }
+ rb_ary_push(av, obj);
+ }
+
+ if(m->cleanup())
+ delete valuelist;
+ else
+ *(m->var()) = av;
+ }
+ break;
+ default:
+ m->unsupported();
+ break;
+ }
+}
+
+#define DEF_LIST_MARSHALLER(ListIdent,ItemList,Item) namespace { char ListIdent##STR[] = #Item; }; \
+ Marshall::HandlerFn marshall_##ListIdent = marshall_ItemList<Item,ItemList,ListIdent##STR>;
+
+DEF_LIST_MARSHALLER( KFileItemList, QPtrList<KFileItem>, KFileItem )
+DEF_LIST_MARSHALLER( KMainWindowList, QPtrList<KMainWindow>, KMainWindow )
+DEF_LIST_MARSHALLER( KActionList, QPtrList<KAction>, KAction )
+DEF_LIST_MARSHALLER( DCOPObjectList, QPtrList<DCOPObject>, DCOPObject )
+DEF_LIST_MARSHALLER( KDockWidgetList, QPtrList<KDockWidget>, KDockWidget )
+DEF_LIST_MARSHALLER( KFileTreeBranch, QPtrList<KFileTreeBranch>, KFileTreeBranch )
+DEF_LIST_MARSHALLER( KFileTreeViewItem, QPtrList<KFileTreeViewItem>, KFileTreeViewItem )
+DEF_LIST_MARSHALLER( KPartList, QPtrList<KParts::Part>, KParts::Part )
+DEF_LIST_MARSHALLER( KPartPluginList, QPtrList<KParts::Plugin>, KParts::Plugin )
+DEF_LIST_MARSHALLER( KPartReadOnlyPartList, QPtrList<KParts::ReadOnlyPart>, KParts::ReadOnlyPart )
+DEF_LIST_MARSHALLER( KServiceTypeProfileList, QPtrList<KServiceTypeProfile>, KServiceTypeProfile )
+
+template <class Item, class ItemList, class ItemListIterator, const char *ItemSTR >
+void marshall_ValueItemList(Marshall *m) {
+ switch(m->action()) {
+ case Marshall::FromVALUE:
+ {
+ VALUE list = *(m->var());
+ if (TYPE(list) != T_ARRAY) {
+ m->item().s_voidp = 0;
+ break;
+ }
+ int count = RARRAY(list)->len;
+ ItemList *cpplist = new ItemList;
+ long i;
+ for(i = 0; i < count; i++) {
+ VALUE item = rb_ary_entry(list, i);
+ // TODO do type checking!
+ smokeruby_object *o = value_obj_info(item);
+ if(!o || !o->ptr)
+ continue;
+ void *ptr = o->ptr;
+ ptr = o->smoke->cast(
+ ptr, // pointer
+ o->classId, // from
+ o->smoke->idClass(ItemSTR) // to
+ );
+ cpplist->append(*(Item*)ptr);
+ }
+
+ m->item().s_voidp = cpplist;
+ m->next();
+
+ if(m->cleanup()) {
+ rb_ary_clear(list);
+ for(ItemListIterator it = cpplist->begin();
+ it != cpplist->end();
+ ++it) {
+ VALUE obj = getPointerObject((void*)&(*it));
+ rb_ary_push(list, obj);
+ }
+ delete cpplist;
+ }
+ }
+ break;
+ case Marshall::ToVALUE:
+ {
+ ItemList *valuelist = (ItemList*)m->item().s_voidp;
+ if(!valuelist) {
+ *(m->var()) = Qnil;
+ break;
+ }
+
+ VALUE av = rb_ary_new();
+
+ int ix = m->smoke()->idClass(ItemSTR);
+ const char * className = m->smoke()->binding->className(ix);
+
+ for(ItemListIterator it = valuelist->begin();
+ it != valuelist->end();
+ ++it) {
+ void *p = &(*it);
+
+ if(m->item().s_voidp == 0) {
+ *(m->var()) = Qnil;
+ break;
+ }
+
+ VALUE obj = getPointerObject(p);
+ if(obj == Qnil) {
+ smokeruby_object * o = ALLOC(smokeruby_object);
+ o->smoke = m->smoke();
+ o->classId = o->smoke->idClass(ItemSTR);
+ o->ptr = p;
+ o->allocated = false;
+ obj = set_obj_info(className, o);
+ }
+ rb_ary_push(av, obj);
+ }
+
+ if(m->cleanup())
+ delete valuelist;
+ else
+ *(m->var()) = av;
+ }
+ break;
+ default:
+ m->unsupported();
+ break;
+ }
+}
+
+#define DEF_VALUELIST_MARSHALLER(ListIdent,ItemList,Item,Itr) namespace { char ListIdent##STR[] = #Item; }; \
+ Marshall::HandlerFn marshall_##ListIdent = marshall_ValueItemList<Item,ItemList,Itr,ListIdent##STR>;
+
+#if KDE_VERSION >= 0x030200
+DEF_VALUELIST_MARSHALLER( ChoicesList, QValueList<KConfigSkeleton::ItemEnum::Choice>, KConfigSkeleton::ItemEnum::Choice, QValueList<KConfigSkeleton::ItemEnum::Choice>::Iterator )
+#endif
+DEF_VALUELIST_MARSHALLER( KAboutPersonList, QValueList<KAboutPerson>, KAboutPerson, QValueList<KAboutPerson>::Iterator )
+DEF_VALUELIST_MARSHALLER( KAboutTranslatorList, QValueList<KAboutTranslator>, KAboutTranslator, QValueList<KAboutTranslator>::Iterator )
+DEF_VALUELIST_MARSHALLER( KIOCopyInfoList, QValueList<KIO::CopyInfo>, KIO::CopyInfo, QValueList<KIO::CopyInfo>::Iterator )
+DEF_VALUELIST_MARSHALLER( KServiceOfferList, QValueList<KServiceOffer>, KServiceOffer, QValueList<KServiceOffer>::Iterator )
+DEF_VALUELIST_MARSHALLER( UDSEntry, QValueList<KIO::UDSAtom>, KIO::UDSAtom, QValueList<KIO::UDSAtom>::Iterator )
+
+template <class Key, class Value, class ItemMapIterator, const char *KeySTR, const char *ValueSTR >
+void marshall_Map(Marshall *m) {
+ switch(m->action()) {
+ case Marshall::FromVALUE:
+ {
+ VALUE hash = *(m->var());
+ if (TYPE(hash) != T_HASH) {
+ m->item().s_voidp = 0;
+ break;
+ }
+
+ QMap<Key,Value> * map = new QMap<Key,Value>;
+
+ // Convert the ruby hash to an array of key/value arrays
+ VALUE temp = rb_funcall(hash, rb_intern("to_a"), 0);
+
+ for (long i = 0; i < RARRAY(temp)->len; i++) {
+ VALUE key = rb_ary_entry(rb_ary_entry(temp, i), 0);
+ VALUE value = rb_ary_entry(rb_ary_entry(temp, i), 1);
+
+ smokeruby_object *o = value_obj_info(key);
+ if( !o || !o->ptr)
+ continue;
+ void * key_ptr = o->ptr;
+ key_ptr = o->smoke->cast(key_ptr, o->classId, o->smoke->idClass(KeySTR));
+
+ o = value_obj_info(value);
+ if( !o || !o->ptr)
+ continue;
+ void * val_ptr = o->ptr;
+ val_ptr = o->smoke->cast(val_ptr, o->classId, o->smoke->idClass(ValueSTR));
+
+ (*map)[(Key)*(Key*)key_ptr] = (Value)*(Value*)val_ptr;
+ }
+
+ m->item().s_voidp = map;
+ m->next();
+
+ if(m->cleanup())
+ delete map;
+ }
+ break;
+ case Marshall::ToVALUE:
+ {
+ QMap<Key,Value> *map = (QMap<Key,Value>*)m->item().s_voidp;
+ if(!map) {
+ *(m->var()) = Qnil;
+ break;
+ }
+
+ VALUE hv = rb_hash_new();
+
+ int key_ix = m->smoke()->idClass(KeySTR);
+ const char * key_className = m->smoke()->binding->className(key_ix);
+
+ int val_ix = m->smoke()->idClass(ValueSTR);
+ const char * val_className = m->smoke()->binding->className(val_ix);
+
+ ItemMapIterator it;
+ for (it = map->begin(); it != map->end(); ++it) {
+ void *key_p = new Key(it.key());
+ VALUE key_obj = getPointerObject(key_p);
+ smokeruby_object * o;
+
+ if (key_obj == Qnil) {
+ o = ALLOC(smokeruby_object);
+ o->classId = m->smoke()->idClass(KeySTR);
+ o->smoke = m->smoke();
+ o->ptr = key_p;
+ o->allocated = true;
+ key_obj = set_obj_info(key_className, o);
+ }
+
+ void *val_p = new Value(it.data());
+ VALUE value_obj = getPointerObject(val_p);
+
+ if (value_obj == Qnil) {
+ o = ALLOC(smokeruby_object);
+ o->classId = m->smoke()->idClass(ValueSTR);
+ o->smoke = m->smoke();
+ o->ptr = val_p;
+ o->allocated = true;
+ value_obj = set_obj_info(val_className, o);
+ }
+
+ rb_hash_aset(hv, key_obj, value_obj);
+ }
+
+ *(m->var()) = hv;
+ m->next();
+
+ if(m->cleanup())
+ delete map;
+ }
+ break;
+ default:
+ m->unsupported();
+ break;
+ }
+}
+
+#define DEF_MAP_MARSHALLER(MapIdent,Key,Value) namespace { char KeyIdent##STR[] = #Key; char ValueIdent##STR[] = #Value; }; \
+ Marshall::HandlerFn marshall_##MapIdent = marshall_Map<Key, Value,QMap<Key,Value>::Iterator,KeyIdent##STR, ValueIdent##STR>;
+
+DEF_MAP_MARSHALLER( QMapKEntryKeyKEntry, KEntryKey, KEntry )
+
+void marshall_QMapQCStringDCOPRef(Marshall *m) {
+ switch(m->action()) {
+ case Marshall::FromVALUE:
+ {
+ VALUE hash = *(m->var());
+ if (TYPE(hash) != T_HASH) {
+ m->item().s_voidp = 0;
+ break;
+ }
+
+ QMap<QCString,DCOPRef> * map = new QMap<QCString,DCOPRef>;
+
+ // Convert the ruby hash to an array of key/value arrays
+ VALUE temp = rb_funcall(hash, rb_intern("to_a"), 0);
+
+ for (long i = 0; i < RARRAY(temp)->len; i++) {
+ VALUE key = rb_ary_entry(rb_ary_entry(temp, i), 0);
+ VALUE value = rb_ary_entry(rb_ary_entry(temp, i), 1);
+
+ smokeruby_object *o = value_obj_info(value);
+ if( !o || !o->ptr)
+ continue;
+ void * ptr = o->ptr;
+ ptr = o->smoke->cast(ptr, o->classId, o->smoke->idClass("DCOPRef"));
+
+ (*map)[QCString(StringValuePtr(key))] = (DCOPRef)*(DCOPRef*)ptr;
+ }
+
+ m->item().s_voidp = map;
+ m->next();
+
+ if(m->cleanup())
+ delete map;
+ }
+ break;
+ case Marshall::ToVALUE:
+ {
+ QMap<QCString,DCOPRef> *map = (QMap<QCString,DCOPRef>*)m->item().s_voidp;
+ if(!map) {
+ *(m->var()) = Qnil;
+ break;
+ }
+
+ VALUE hv = rb_hash_new();
+
+ QMap<QCString,DCOPRef>::Iterator it;
+ for (it = map->begin(); it != map->end(); ++it) {
+ void *p = new DCOPRef(it.data());
+ VALUE obj = getPointerObject(p);
+
+ if (obj == Qnil) {
+ smokeruby_object * o = ALLOC(smokeruby_object);
+ o->classId = m->smoke()->idClass("DCOPRef");
+ o->smoke = m->smoke();
+ o->ptr = p;
+ o->allocated = true;
+ obj = set_obj_info("KDE::DCOPRef", o);
+ }
+
+ rb_hash_aset(hv, rb_str_new2((const char *) it.key()), obj);
+ }
+
+ *(m->var()) = hv;
+ m->next();
+
+ if(m->cleanup())
+ delete map;
+ }
+ break;
+ default:
+ m->unsupported();
+ break;
+ }
+}
+
+TypeHandler KDE_handlers[] = {
+ { "QCStringList", marshall_QCStringList },
+ { "KCmdLineOptions*", marshall_KCmdLineOptions },
+ { "KActionPtrList", marshall_KActionList },
+ { "QPtrList<KAction>", marshall_KActionList },
+ { "QPtrList<KAction>&", marshall_KActionList },
+ { "KMimeType::List", marshall_KMimeTypeList },
+ { "KMimeType::Ptr", marshall_KMimeTypePtr },
+ { "KService::Ptr", marshall_KServicePtr },
+ { "KService::List", marshall_KServiceList },
+ { "KServiceGroup::List", marshall_KServiceGroupList },
+ { "KServiceGroup::Ptr", marshall_KServiceGroupPtr },
+#if KDE_VERSION >= 0x030200
+ { "KMountPoint::List", marshall_KMountPointList },
+ { "KPluginInfo::List", marshall_KPluginInfoList },
+ { "QValueList<KConfigSkeleton::ItemEnum::Choice>", marshall_ChoicesList },
+ { "QValueList<KConfigSkeleton::ItemEnum::Choice>&", marshall_ChoicesList },
+#endif
+ { "KServiceType::List", marshall_KServiceTypeList },
+ { "KTrader::OfferList", marshall_KTraderOfferList },
+ { "KURL::List", marshall_KURLList },
+ { "KURL::List&", marshall_KURLList },
+ { "KFileItemList", marshall_KFileItemList },
+ { "KFileItemList*", marshall_KFileItemList },
+ { "QPtrList<KMainWindow>*", marshall_KMainWindowList },
+ { "QPtrList<DCOPObject>", marshall_DCOPObjectList },
+ { "QPtrList<KDockWidget>&", marshall_KDockWidgetList },
+ { "QPtrList<KDockWidget>*", marshall_KDockWidgetList },
+ { "KFileTreeBranchList&", marshall_KFileTreeBranch },
+ { "KFileTreeViewItemList&", marshall_KFileTreeViewItem },
+ { "QPtrList<KParts::Part>*", marshall_KPartList },
+ { "QPtrList<KParts::Plugin>", marshall_KPartPluginList },
+ { "QPtrList<KParts::ReadOnlyPart>", marshall_KPartReadOnlyPartList },
+ { "QPtrList<KServiceTypeProfile>&", marshall_KServiceTypeProfileList },
+ { "QValueList<KAction*>", marshall_KActionPtrList },
+ { "KActionPtrList", marshall_KActionPtrList },
+ { "QValueList<KAboutPerson>", marshall_KAboutPersonList },
+ { "QValueList<KAboutTranslator>", marshall_KAboutTranslatorList },
+ { "QValueList<KIO::CopyInfo>&", marshall_KIOCopyInfoList },
+ { "KIO::UDSEntry&", marshall_UDSEntry },
+ { "KIO::UDSEntryList&", marshall_UDSEntryList },
+ { "KServiceTypeProfile::OfferList", marshall_KServiceOfferList },
+ { "KEntryMap", marshall_QMapKEntryKeyKEntry },
+ { "KEntryMap&", marshall_QMapKEntryKeyKEntry },
+ { "KEntryMap*", marshall_QMapKEntryKeyKEntry },
+ { "QMap<QCString,DCOPRef>", marshall_QMapQCStringDCOPRef },
+ { "QValueList<WId>&", marshall_WIdList },
+ { "QValueList<WId>", marshall_WIdList },
+ { 0, 0 }
+};
diff --git a/korundum/rubylib/korundum/lib/KDE/Korundum.rb b/korundum/rubylib/korundum/lib/KDE/Korundum.rb
new file mode 100644
index 00000000..101d3e30
--- /dev/null
+++ b/korundum/rubylib/korundum/lib/KDE/Korundum.rb
@@ -0,0 +1 @@
+require 'korundum'
diff --git a/korundum/rubylib/korundum/lib/KDE/Makefile.am b/korundum/rubylib/korundum/lib/KDE/Makefile.am
new file mode 100644
index 00000000..3f7b0c53
--- /dev/null
+++ b/korundum/rubylib/korundum/lib/KDE/Makefile.am
@@ -0,0 +1,5 @@
+kderubylibdir = $(RUBY_SITEDIR)/KDE
+kderubylib_DATA = korundum.rb
+
+rubylibdir = $(RUBY_SITEDIR)
+rubylib_DATA = Korundum.rb
diff --git a/korundum/rubylib/korundum/lib/KDE/korundum.rb b/korundum/rubylib/korundum/lib/KDE/korundum.rb
new file mode 100644
index 00000000..40c87260
--- /dev/null
+++ b/korundum/rubylib/korundum/lib/KDE/korundum.rb
@@ -0,0 +1,1391 @@
+=begin
+/***************************************************************************
+ Korundum.rb - KDE specific ruby runtime, dcop etc.
+ -------------------
+ begin : Sun Sep 28 2003
+ copyright : (C) 2003-2006 by Richard Dale
+ email : Richard_Dale@tipitina.demon.co.uk
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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. *
+ * *
+ ***************************************************************************/
+=end
+
+module KDE
+ DCOPMeta = {}
+
+ # An entry for each dcop signal or slot
+ # Example
+ # int foobar(QString,bool)
+ # :name is 'foobar'
+ # :full_name is 'foobar(QString,bool)'
+ # :arg_types is 'QString,bool'
+ # :reply_type is 'int'
+ DCOPMember = Struct.new :name, :full_name, :arg_types, :reply_type
+
+ # If the class with the 'k_dcop' slots declaration is not a subclass of DCOPObject,
+ # then 'dcop_object' holds a instance of DCOPObject for the class to use as a
+ # proxy. For subclasses of DCOPObject, 'dcop_object' will always be nil
+ class DCOPMetaInfo
+ attr_accessor :dcop_object, :changed
+ attr_reader :k_dcop_signals, :k_dcop
+
+ def initialize(aClass)
+ DCOPMeta[aClass.name] = self
+ @dcop_object = nil
+ @k_dcop_signals = {}
+ @k_dcop = {}
+ @changed = false
+ end
+
+ def add_signals(signal_list)
+ signal_list.each do |signal|
+ signal = DCOPClient.normalizeFunctionSignature(signal)
+ if signal =~ /^([\w,<>:]*)\s+([^\s]*)\((.*)\)/
+ args = DCOPClient.normalizeFunctionSignature($3)
+ @k_dcop_signals[$2] = DCOPMember.new($2, $2 + "(" + args + ")", args, $1)
+ else
+ qWarning( "Invalid DCOP signal format: '#{signal}'" )
+ end
+ end
+ end
+
+ def add_slots(slot_list)
+ slot_list.each do |slot|
+ if slot =~ /^([\w,<>:]*)\s+([^\s]*)\((.*)\)/
+ args = DCOPClient.normalizeFunctionSignature($3)
+ @k_dcop[$2] = DCOPMember.new($2, $1 + ' ' + $2 + "(" + args + ")", args, $1)
+ else
+ qWarning( "Invalid DCOP slot format: '#{slot}'" )
+ end
+ end
+ end
+ end # DCOPMetaInfo
+
+ def KDE.hasDCOPSignals(aClass)
+ classname = aClass.name if aClass.is_a? Module
+ meta = DCOPMeta[classname]
+ return !meta.nil? && meta.k_dcop_signals.length > 0
+ end
+
+ def KDE.hasDCOPSlots(aClass)
+ classname = aClass.name if aClass.is_a? Module
+ meta = DCOPMeta[classname]
+ return !meta.nil? && meta.k_dcop.length > 0
+ end
+
+ def KDE.getDCOPSignalNames(aClass)
+ classname = aClass.name if aClass.is_a? Module
+ signals = DCOPMeta[classname].k_dcop_signals
+ return signals.keys
+ end
+
+ module Internal
+ def Internal.fullSignalName(instance, signalName)
+ classname = instance.class.name if instance.class.is_a? Module
+ signals = DCOPMeta[classname].k_dcop_signals
+ return signals[signalName].full_name
+ end
+ end
+
+ class KDE::DCOPObject
+ def initialize(*k)
+ super
+ end
+
+ def process(fun, data, replyType, replyData)
+ if fun == 'functions()' or fun == 'interfaces()'
+ return super
+ end
+
+ slots = DCOPMeta[@client.class.name].k_dcop
+ dcop_slot = slots[fun.sub(/\(.*/, '')]
+ if dcop_slot.nil?
+ # Can't find an entry for the slot being called? This shouldn't happen..
+ return false
+ end
+
+ replyType << dcop_slot.reply_type
+ KDE::dcop_process( @client,
+ dcop_slot.name,
+ Qt::Internal::getMocArguments(fun),
+ data,
+ replyType,
+ (replyType == 'void' or replyType == 'ASYNC') ? nil : Qt::Internal::getMocArguments(replyType),
+ replyData )
+ end
+
+ def interfaces()
+ ifaces = super()
+ return ifaces << @client.class.name
+ end
+
+ def functions()
+ funcs = super()
+ return funcs + @functions
+ end
+
+ def functions=(funcs)
+ @functions = funcs
+ end
+
+ # If a ruby class has 'k_dcop' slots declarations, but isn't a
+ # subclass of DCOPObject, then keep an instance of it
+ def client=(obj)
+ @client = obj
+ end
+
+ def inspect
+ str = super
+ if @functions != nil
+ str.sub(/>$/, " objId=%s, functions=Array (%d element(s))>" % [objId.inspect, functions.length])
+ end
+ end
+
+ def pretty_print(pp)
+ str = to_s
+ if @functions != nil
+ pp.text str.sub(/>$/, "\n objId=%s,\n functions=Array (%d element(s))>" % [objId.inspect, functions.length])
+ end
+ end
+ end
+
+ # If a class contains a k_dcop slots list declaration, then create a DCOPObject
+ # associated with it
+ def KDE.createDCOPObject(instance)
+ meta = DCOPMeta[instance.class.name]
+ return nil if meta.nil?
+
+ if meta.dcop_object.nil? or meta.changed
+ funcs = []
+ meta.k_dcop.each_value do |value|
+ sig = value.reply_type + ' ' + value.name + '(' + value.arg_types + ')'
+ funcs << sig
+ end
+ meta.changed = false
+ if instance.kind_of? DCOPObject
+ instance.functions = funcs
+ instance.client = instance
+ return nil
+ else
+ if meta.dcop_object.nil?
+ # Only ever allocate a single instance of a DCOPObject if the
+ # class isn't a subclass of DCOPObject
+ meta.dcop_object = DCOPObject.new(instance.class.name)
+ meta.dcop_object.client = instance
+ end
+ meta.dcop_object.functions = funcs
+ end
+ end
+
+ return meta.dcop_object
+ end
+
+ class DCOPRef < Qt::Base
+ def method_missing(*k)
+ # Enables DCOPRef calls to be made like this:
+ #
+ # dcopRef = DCOPRef.new("dcopslot", "MyWidget")
+ # result = dcopRef.getPoint("Hello from dcopcall")
+ begin
+ # First look for a method in the Smoke runtime.
+ # If not found, then throw an exception and try dcop.
+ super(*k)
+ rescue
+ dcopArgs = k[1, k.length-1]
+ dcopArgs << NoEventLoop << -1
+ method = k[0].id2name
+ # Make 'parrot.age = 7' a synonym for 'parrot.setAge(7)'
+ method = 'set' + method[0,1].upcase + method[1,method.length].sub("=", "") if method =~ /.*[^-+%\/|]=$/
+
+ # If the method name contains underscores, convert to camel case
+ while method =~ /([^_]*)_(.)(.*)/
+ method = $1 + $2.upcase + $3
+ end
+
+ # Get the functions() for this dcop ref and
+ # cache method_name => full_type_signature in a hash
+ if @functions.nil?
+ @functions = {}
+ funcs = call("functions()")
+ if funcs.nil?
+ return nil
+ end
+ funcs.each do |func|
+ if func =~ /^([\w,<>:]*)\s+(.*)(\(.*\))/
+ return_type = $1
+ name = $2
+ args = $3
+ if args =~ / /
+ # Remove any arg names
+ args.gsub!(/ \w*/, "")
+ end
+
+ # Make thing? a synonym for isThing() or hasThing()
+ if name =~ /^(is|has)(.)(.*)/
+ predicate = $2.downcase + $3 + '?'
+ if @functions[predicate].nil?
+ @functions[predicate] = return_type + " " + name + args
+ end
+ end
+
+ if @functions[name].nil?
+ @functions[name] = return_type + " " + name + args
+ else
+ # If a function name is overloaded, just keep a single name entry in
+ # the hash, not all the full type signatures. Then leave dcopTypeNames()
+ # to try and resolve the ambiguous call from the ruby arg types passed.
+ @functions.delete(name)
+ @functions[name] = name
+ end
+ end
+ end
+ end
+
+ method = @functions[method]
+ if method.nil?
+ qWarning( "DCOPRef: call #{k[0].id2name}() not found" )
+ return
+ end
+
+ return callExt(method, *dcopArgs)
+ end
+ end
+
+ def dcopTypeNames(*k)
+ typeNames = "("
+ k.each do |arg|
+ if arg.kind_of? Integer
+ typeNames << "int,"
+ elsif arg.kind_of? Float
+ typeNames << "double,"
+ elsif arg.kind_of? Array
+ typeNames << "QStringList,"
+ elsif arg.kind_of? String
+ typeNames << "QString,"
+ elsif arg.kind_of? Qt::Base
+ typeNames << arg.class.name + ","
+ elsif arg.instance_of? FalseClass or arg.instance_of? TrueClass
+ typeNames << "bool,"
+ end
+ end
+ typeNames.sub!(/,$/, '')
+ typeNames.gsub!(/Qt::/, 'Q')
+ typeNames.gsub!(/KDE::/, 'K')
+ typeNames << ")"
+ return typeNames
+ end
+
+ def call(fun, *k)
+ k << NoEventLoop << -1
+ callExt(fun, *k)
+ end
+
+ def callExt(fun, *k)
+ if isNull
+ qWarning( "DCOPRef: call #{fun} on null reference error" )
+ return
+ end
+ sig = fun
+ if fun.index('(') == nil
+ sig << dcopTypeNames(*k[0, k.length - 2])
+ end
+ dc = dcopClient()
+ if !dc || !dc.isAttached
+ qWarning( "DCOPRef::call(): no DCOP client or client not attached error" )
+ return
+ end
+ if sig =~ /([^\s]*)(\(.*\))/
+ full_name = $1+$2
+ else
+ qWarning( "DCOPRef: call #{fun} invalid format, expecting '<function_name>(<args>)'" )
+ return
+ end
+ return KDE::dcop_call( self,
+ full_name,
+ Qt::Internal::getMocArguments(full_name),
+ *k )
+ end
+
+ def send(fun, *k)
+ if isNull
+ qWarning( "DCOPRef: send #{fun} on null reference error" )
+ end
+ sig = fun
+ if fun.index('(') == nil
+ sig << dcopTypeNames(*k)
+ end
+ dc = dcopClient()
+ if !dc || !dc.isAttached
+ qWarning( "DCOPRef::send(): no DCOP client or client not attached error" )
+ return
+ end
+ if !sig =~ /^([^\s]*)(\(.*\))/
+ qWarning( "DCOPRef: send #{sig} invalid format, expecting '<function_name>(<args>)'" )
+ return
+ end
+ return KDE::dcop_send( self,
+ fun,
+ Qt::Internal::getMocArguments(sig),
+ *k )
+ end
+
+ def methods
+ if @functions.nil?
+ functions()
+ end
+
+ result = super + @functions.keys.map {|k| k.sub(/^(set)([A-Z])(.*)/) { $2.downcase + $3 + '=' } }
+ return result.uniq
+ end
+
+ def inspect
+ str = super
+ str.sub(/>$/, " app=%s, obj=%s>" % [app.inspect, obj.inspect])
+ end
+
+ def pretty_print(pp)
+ str = to_s
+ pp.text str.sub(/>$/, "\n app=%s,\n obj=%s>" % [app.inspect, obj.inspect])
+ end
+
+ def type(*args)
+ method_missing(:type, *args)
+ end
+ end
+
+ def CmdLineArgs::init(*k)
+ if k.length > 0
+ if k[0].kind_of? Array
+ # If init() is passed an array as the first argument, assume it's ARGV.
+ # Then convert to a pair of args 'ARGV.length+1, [$0]+ARGV'
+ array = k.shift
+ super(*([array.length+1] + [[$0] + array] + k))
+ elsif k[0].kind_of? KDE::AboutData
+ super(1, [$0], k[0])
+ end
+ else
+ super
+ end
+ end
+
+ # A sane alternative to the strange looking C++ template version,
+ # this takes a variable number of ruby args as classes to restore
+ def MainWindow::kRestoreMainWindows(*k)
+ n = 1
+ while MainWindow.canBeRestored(n)
+ className = MainWindow.classNameOfToplevel(n)
+ k.each do |klass|
+ if klass.name == className
+ klass.new.restore(n)
+ end
+ end
+ n += 1
+ end
+ end
+
+ class AboutData
+ def inspect
+ str = super
+ str.sub!(/>$/, " appName=%s, copyrightStatement=%s, programName=%s, version=%s, shortDescription=%s, homepage=%s, bugAddress=%s>" %
+ [appName.inspect, copyrightStatement.inspect, programName.inspect, version.inspect,
+ shortDescription.inspect, homepage.inspect, bugAddress.inspect] )
+ length = authors.length
+ if length > 0
+ str.sub!(/>$/, ", authors=Array (%d element(s))>" % length)
+ end
+ length = credits.length
+ if length > 0
+ str.sub!(/>$/, ", credits=Array (%d element(s))>" % length)
+ end
+ length = translators.length
+ if length > 0
+ str.sub!(/>$/, ", translators=Array (%d element(s))>" % length)
+ end
+ return str
+ end
+
+ def pretty_print(pp)
+ str = to_s
+ str.sub!(/>$/, "\n appName=%s,\n copyrightStatement=%s,\n programName=%s,\n version=%s,\n shortDescription=%s,\n homepage=%s,\n bugAddress=%s>" %
+ [appName.inspect, copyrightStatement.inspect, programName.inspect, version.inspect,
+ shortDescription.inspect, homepage.inspect, bugAddress.inspect] )
+ length = authors.length
+ if length > 0
+ str.sub!(/>$/, ",\n authors=Array (%d element(s))>" % length)
+ end
+ length = credits.length
+ if length > 0
+ str.sub!(/>$/, ",\n credits=Array (%d element(s))>" % length)
+ end
+ length = translators.length
+ if length > 0
+ str.sub!(/>$/, ",\n translators=Array (%d element(s))>" % length)
+ end
+ pp.text str
+ end
+ end
+
+ class AboutPerson
+ def inspect
+ str = super
+ str.sub(/>$/, " emailAddress=%s, name=%s, task=%s, webAddress=%s>" %
+ [emailAddress.inspect, name.inspect, task.inspect, webAddress.inspect] )
+ end
+
+ def pretty_print(pp)
+ str = to_s
+ pp.text str.sub(/>$/, "\n emailAddress=%s,\n name=%s,\n task=%s,\n webAddress=%s>" %
+ [emailAddress.inspect, name.inspect, task.inspect, webAddress.inspect] )
+ end
+
+ def name(*args)
+ method_missing(:name, *args)
+ end
+ end
+
+ class AboutTranslator
+ def inspect
+ str = super
+ str.sub(/>$/, " emailAddress=%s, name=%s>" %
+ [emailAddress.inspect, name.inspect] )
+ end
+
+ def pretty_print(pp)
+ str = to_s
+ pp.text str.sub(/>$/, "\n emailAddress=%s,\n name=%s>" %
+ [emailAddress.inspect, name.inspect] )
+ end
+
+ def name(*args)
+ method_missing(:name, *args)
+ end
+ end
+
+ class AccelShortcutList
+ def name(*args)
+ method_missing(:name, *args)
+ end
+ end
+
+ class ActionPtrShortcutList
+ def name(*args)
+ method_missing(:name, *args)
+ end
+ end
+
+ class ActionShortcutList
+ def name(*args)
+ method_missing(:name, *args)
+ end
+ end
+
+ class Application
+ def initialize(*k)
+ super
+ $kapp = self
+ end
+
+ # Delete the underlying C++ instance after exec returns
+ # Otherwise, rb_gc_call_finalizer_at_exit() can delete
+ # stuff that KDE::Application still needs for its cleanup.
+ def exec
+ method_missing(:exec)
+ self.dispose
+ Qt::Internal.application_terminated = true
+ end
+ end
+
+ class Archive
+ def open(*args)
+ method_missing(:open, *args)
+ end
+ end
+
+ class ArchiveEntry
+ def name(*args)
+ method_missing(:name, *args)
+ end
+ end
+
+ class BookmarkDrag
+ def format(*args)
+ method_missing(:format, *args)
+ end
+ end
+
+ class CModule
+ def load(*args)
+ method_missing(:load, *args)
+ end
+ end
+
+ class Catalogue
+ def name(*args)
+ method_missing(:name, *args)
+ end
+ end
+
+ class ColorDrag
+ def format(*args)
+ method_missing(:format, *args)
+ end
+ end
+
+ class CustomMenuEditor
+ def load(*args)
+ method_missing(:load, *args)
+ end
+ end
+
+ class FileItem
+ def name(*args)
+ method_missing(:name, *args)
+ end
+ end
+
+ class FileMetaInfoGroup
+ def name(*args)
+ method_missing(:name, *args)
+ end
+ end
+
+ class FileMetaInfoItem
+ def type(*args)
+ method_missing(:type, *args)
+ end
+ end
+
+ class FileTreeBranch
+ def name(*args)
+ method_missing(:name, *args)
+ end
+ end
+
+ class FilterDev
+ def open(*args)
+ method_missing(:open, *args)
+ end
+ end
+
+ class HTMLView
+ def print(*args)
+ method_missing(:print, *args)
+ end
+ end
+
+ class Icon
+ def type(*args)
+ method_missing(:type, *args)
+ end
+ end
+
+ class ImageEffect
+ def hash(*args)
+ method_missing(:hash, *args)
+ end
+ end
+
+ class ImageIO
+ def type(*args)
+ method_missing(:type, *args)
+ end
+ end
+
+ class ListView
+ include Enumerable
+
+ def each
+ it = Qt::ListViewItemIterator.new(self)
+ while it.current
+ yield it.current
+ it += 1
+ end
+ end
+
+ def sort(*args)
+ method_missing(:sort, *args)
+ end
+ end
+
+ class ListViewItem
+ include Enumerable
+
+ def each
+ it = Qt::ListViewItemIterator.new(self)
+ while it.current
+ yield it.current
+ it += 1
+ end
+ end
+
+ def sort(*args)
+ method_missing(:sort, *args)
+ end
+
+ def inspect
+ str = super
+ str.sub!(/>$/, "")
+ for i in 0..(listView.columns - 1)
+ str << " text%d=%s," % [i, self.text(i)]
+ end
+ str.sub!(/,?$/, ">")
+ end
+
+ def pretty_print(pp)
+ str = to_s
+ str.sub!(/>$/, "")
+ for i in 0..(listView.columns - 1)
+ str << " text%d=%s," % [i, self.text(i)]
+ end
+ str.sub!(/,?$/, ">")
+ pp.text str
+ end
+ end
+
+ class MainWindowInterface
+ def raise(*args)
+ method_missing(:raise, *args)
+ end
+ end
+
+ class MdiChildView
+ def raise(*args)
+ method_missing(:raise, *args)
+ end
+ end
+
+ class MimeType
+ def load(*args)
+ method_missing(:load, *args)
+ end
+ end
+
+ class MultiTabBarButton
+ def id(*args)
+ method_missing(:id, *args)
+ end
+ end
+
+ class MultipleDrag
+ def format(*args)
+ method_missing(:format, *args)
+ end
+ end
+
+ class NamedCommand
+ def name(*args)
+ method_missing(:name, *args)
+ end
+ end
+
+ class NewStuff
+ def type(*args)
+ method_missing(:type, *args)
+ end
+ end
+
+ class OCRDialog
+ def id(*args)
+ method_missing(:id, *args)
+ end
+ end
+
+ class Palette
+ def name(*args)
+ method_missing(:name, *args)
+ end
+ end
+
+ class PanelApplet
+ def type(*args)
+ method_missing(:type, *args)
+ end
+ end
+
+ class PanelExtension
+ def type(*args)
+ method_missing(:type, *args)
+ end
+ end
+
+ class Pixmap
+ def load(*args)
+ method_missing(:load, *args)
+ end
+ end
+
+ class PixmapEffect
+ def hash(*args)
+ method_missing(:hash, *args)
+ end
+ end
+
+ class PluginInfo
+ def load(*args)
+ method_missing(:load, *args)
+ end
+
+ def name(*args)
+ method_missing(:name, *args)
+ end
+ end
+
+ class PluginSelector
+ def load(*args)
+ method_missing(:load, *args)
+ end
+ end
+
+ class PopupFrame
+ def exec(*args)
+ method_missing(:exec, *args)
+ end
+ end
+
+ class PrintAction
+ def print(*args)
+ method_missing(:print, *args)
+ end
+ end
+
+ class Printer
+ def abort(*args)
+ method_missing(:abort, *args)
+ end
+ end
+
+ class Progress
+ def format(*args)
+ method_missing(:format, *args)
+ end
+ end
+
+ class ProtocolInfo
+ def exec(*args)
+ method_missing(:exec, *args)
+ end
+
+ def load(*args)
+ method_missing(:load, *args)
+ end
+
+ def name(*args)
+ method_missing(:name, *args)
+ end
+ end
+
+ class Pty
+ def open(*args)
+ method_missing(:open, *args)
+ end
+ end
+
+ class Run
+ def abort(*args)
+ method_missing(:abort, *args)
+ end
+ end
+
+ class SSLCertDlgRet
+ def send(*args)
+ method_missing(:send, *args)
+ end
+ end
+
+ class SSLPKCS12
+ def name(*args)
+ method_missing(:name, *args)
+ end
+ end
+
+ class SSLPKCS7
+ def name(*args)
+ method_missing(:name, *args)
+ end
+ end
+
+ class SSLSettings
+ def load(*args)
+ method_missing(:load, *args)
+ end
+ end
+
+ class SaveFile
+ def abort(*args)
+ method_missing(:abort, *args)
+ end
+
+ def name(*args)
+ method_missing(:name, *args)
+ end
+ end
+
+ class ScanDialog
+ def id(*args)
+ method_missing(:id, *args)
+ end
+ end
+
+ class Service
+ def inspect
+ str = super
+ str.sub(/>$/, " library=%s, type=%s, name=%s>" % [library.inspect, type.inspect, name.inspect])
+ end
+
+ def pretty_print(pp)
+ str = to_s
+ pp.text str.sub(/>$/, "\n library=%s,\n type=%s,\n name=%s>" % [library.inspect, type.inspect, name.inspect])
+ end
+
+ def exec(*args)
+ method_missing(:exec, *args)
+ end
+
+ def load(*args)
+ method_missing(:load, *args)
+ end
+
+ def name(*args)
+ method_missing(:name, *args)
+ end
+
+ def type(*args)
+ method_missing(:type, *args)
+ end
+ end
+
+ class ServiceGroup
+ def load(*args)
+ method_missing(:load, *args)
+ end
+
+ def name(*args)
+ method_missing(:name, *args)
+ end
+ end
+
+ class ServiceSeparator
+ def load(*args)
+ method_missing(:load, *args)
+ end
+
+ def name(*args)
+ method_missing(:name, *args)
+ end
+ end
+
+ class ServiceType
+ def load(*args)
+ method_missing(:load, *args)
+ end
+
+ def name(*args)
+ method_missing(:name, *args)
+ end
+ end
+
+ class Socks
+ def select(*args)
+ method_missing(:select, *args)
+ end
+
+ def send(*args)
+ method_missing(:send, *args)
+ end
+ end
+
+ class StdAccel
+ def name(*args)
+ method_missing(:name, *args)
+ end
+
+ def open(*args)
+ method_missing(:open, *args)
+ end
+
+ def print(*args)
+ method_missing(:print, *args)
+ end
+ end
+
+ class StdAccel::ShortcutList
+ def name(*args)
+ method_missing(:name, *args)
+ end
+ end
+
+ class StdAction
+ def name(*args)
+ method_missing(:name, *args)
+ end
+
+ def open(*args)
+ method_missing(:open, *args)
+ end
+
+ def print(*args)
+ method_missing(:print, *args)
+ end
+ end
+
+ class StdGuiItem
+ def open(*args)
+ method_missing(:open, *args)
+ end
+
+ def print(*args)
+ method_missing(:print, *args)
+ end
+
+ def test(*args)
+ method_missing(:test, *args)
+ end
+ end
+
+ class TempDir
+ def name(*args)
+ method_missing(:name, *args)
+ end
+ end
+
+ class TempFile
+ def name(*args)
+ method_missing(:name, *args)
+ end
+ end
+
+ class ToolBarButton
+ def id(*args)
+ method_missing(:id, *args)
+ end
+ end
+
+ class UniqueApplication
+ def initialize(*k)
+ super
+ $kapp = self
+ end
+
+ # Delete the underlying C++ instance after exec returns
+ # Otherwise, rb_gc_call_finalizer_at_exit() can delete
+ # stuff that KDE::Application still needs for its cleanup.
+ def exec
+ method_missing(:exec)
+ self.dispose
+ Qt::Internal.application_terminated = true
+ end
+ end
+
+ class URIFilterPlugin
+ def name(*args)
+ method_missing(:name, *args)
+ end
+ end
+
+ class URL
+ def inspect
+ str = super
+ str.sub(/>$/, " url=%s, protocol=%s, host=%s, port=%d>" % [url.inspect, protocol.inspect, host.inspect, port])
+ end
+
+ def pretty_print(pp)
+ str = to_s
+ pp.text str.sub(/>$/, "\n url=%s,\n protocol=%s,\n host=%s,\n port=%d>" % [url.inspect, protocol.inspect, host.inspect, port])
+ end
+
+ def split(*args)
+ method_missing(:split, *args)
+ end
+ end
+
+ class URLDrag
+ def format(*args)
+ method_missing(:format, *args)
+ end
+ end
+
+ class VMAllocator
+ def allocate(*args)
+ method_missing(:allocate, *args)
+ end
+ end
+
+ class WindowInfo
+ def display(*args)
+ method_missing(:display, *args)
+ end
+ end
+
+end
+
+module DOM
+ class Attr
+ def name(*args)
+ method_missing(:name, *args)
+ end
+ end
+
+ class DOMString
+ def split(*args)
+ method_missing(:split, *args)
+ end
+ end
+
+ class DocumentType
+ def name(*args)
+ method_missing(:name, *args)
+ end
+ end
+
+ class Event
+ def type(*args)
+ method_missing(:type, *args)
+ end
+ end
+
+ class HTMLAnchorElement
+ def name(*args)
+ method_missing(:name, *args)
+ end
+ end
+
+ class HTMLAnchorElement
+ def type(*args)
+ method_missing(:type, *args)
+ end
+ end
+
+ class HTMLAppletElement
+ def name(*args)
+ method_missing(:name, *args)
+ end
+ end
+
+ class HTMLButtonElement
+ def name(*args)
+ method_missing(:name, *args)
+ end
+ end
+
+ class HTMLButtonElement
+ def type(*args)
+ method_missing(:type, *args)
+ end
+ end
+
+ class HTMLElement
+ def id(*args)
+ method_missing(:id, *args)
+ end
+ end
+
+ class HTMLFormElement
+ def method(*args)
+ method_missing(:method, *args)
+ end
+ end
+
+ class HTMLFormElement
+ def name(*args)
+ method_missing(:name, *args)
+ end
+ end
+
+ class HTMLFrameElement
+ def name(*args)
+ method_missing(:name, *args)
+ end
+ end
+
+ class HTMLIFrameElement
+ def name(*args)
+ method_missing(:name, *args)
+ end
+ end
+
+ class HTMLImageElement
+ def name(*args)
+ method_missing(:name, *args)
+ end
+ end
+
+ class HTMLInputElement
+ def name(*args)
+ method_missing(:name, *args)
+ end
+ end
+
+ class HTMLInputElement
+ def type(*args)
+ method_missing(:type, *args)
+ end
+ end
+
+ class HTMLLIElement
+ def type(*args)
+ method_missing(:type, *args)
+ end
+ end
+
+ class HTMLLinkElement
+ def type(*args)
+ method_missing(:type, *args)
+ end
+ end
+
+ class HTMLMapElement
+ def name(*args)
+ method_missing(:name, *args)
+ end
+ end
+
+ class HTMLMetaElement
+ def name(*args)
+ method_missing(:name, *args)
+ end
+ end
+
+ class HTMLOListElement
+ def type(*args)
+ method_missing(:type, *args)
+ end
+ end
+
+ class HTMLObjectElement
+ def name(*args)
+ method_missing(:name, *args)
+ end
+ end
+
+ class HTMLObjectElement
+ def type(*args)
+ method_missing(:type, *args)
+ end
+ end
+
+ class HTMLParamElement
+ def name(*args)
+ method_missing(:name, *args)
+ end
+ end
+
+ class HTMLParamElement
+ def type(*args)
+ method_missing(:type, *args)
+ end
+ end
+
+ class HTMLScriptElement
+ def type(*args)
+ method_missing(:type, *args)
+ end
+ end
+
+ class HTMLSelectElement
+ def name(*args)
+ method_missing(:name, *args)
+ end
+ end
+
+ class HTMLSelectElement
+ def type(*args)
+ method_missing(:type, *args)
+ end
+ end
+
+ class HTMLStyleElement
+ def type(*args)
+ method_missing(:type, *args)
+ end
+ end
+
+ class HTMLTextAreaElement
+ def name(*args)
+ method_missing(:name, *args)
+ end
+ end
+
+ class HTMLTextAreaElement
+ def type(*args)
+ method_missing(:type, *args)
+ end
+ end
+
+ class HTMLUListElement
+ def type(*args)
+ method_missing(:type, *args)
+ end
+ end
+
+ class StyleSheet
+ def type(*args)
+ method_missing(:type, *args)
+ end
+ end
+
+ class CSSRule
+ def type(*args)
+ method_missing(:type, *args)
+ end
+ end
+
+ class Document
+ def abort(*args)
+ method_missing(:abort, *args)
+ end
+ end
+
+ class Document
+ def load(*args)
+ method_missing(:load, *args)
+ end
+ end
+
+ class HTMLDocument
+ def open(*args)
+ method_missing(:open, *args)
+ end
+ end
+
+ class HTMLInputElement
+ def select(*args)
+ method_missing(:select, *args)
+ end
+ end
+
+ class HTMLTextAreaElement
+ def select(*args)
+ method_missing(:select, *args)
+ end
+ end
+end # DOM
+
+module KIO
+ class Connection
+ def send(*args)
+ method_missing(:send, *args)
+ end
+ end
+
+ class NetRC::AutoLogin
+ def type(*args)
+ method_missing(:type, *args)
+ end
+ end
+
+ class Slave
+ def send(*args)
+ method_missing(:send, *args)
+ end
+ end
+
+ class SlaveBase
+ def exit(*args)
+ method_missing(:exit, *args)
+ end
+ end
+end # KIO
+
+module KNS
+ class Engine
+ def type(*args)
+ method_missing(:type, *args)
+ end
+ end
+
+ class Entry
+ def name(*args)
+ method_missing(:name, *args)
+ end
+
+ def type(*args)
+ method_missing(:type, *args)
+ end
+ end
+
+ class Provider
+ def name(*args)
+ method_missing(:name, *args)
+ end
+ end
+
+ class ProviderLoader
+ def load(*args)
+ method_missing(:load, *args)
+ end
+ end
+end # KNS
+
+module KParts
+ class Event
+ def test(*args)
+ method_missing(:test, *args)
+ end
+ end
+
+ class GUIActivateEvent
+ def test(*args)
+ method_missing(:test, *args)
+ end
+ end
+
+ class OpenURLEvent
+ def test(*args)
+ method_missing(:test, *args)
+ end
+ end
+
+ class PartActivateEvent
+ def test(*args)
+ method_missing(:test, *args)
+ end
+ end
+
+ class PartSelectEvent
+ def test(*args)
+ method_missing(:test, *args)
+ end
+ end
+end # KParts
+
+module Win
+ class Win::WindowInfo
+ def name(*args)
+ method_missing(:name, *args)
+ end
+ end
+end
+
+class Object
+ def RESTORE(klass)
+ n = 1
+ while MainWindow.canBeRestored(n)
+ klass.new.restore(n)
+ n += 1
+ end
+ end
+
+ def I18N_NOOP(x) x end
+ def I18N_NOOP2(comment, x) x end
+end
+
+class Qt::Base
+ def self.k_dcop_signals(*signal_list)
+ meta = KDE::DCOPMeta[self.name] || KDE::DCOPMetaInfo.new(self)
+ meta.add_signals(signal_list)
+ meta.changed = true
+ end
+
+ def self.k_dcop(*slot_list)
+ meta = KDE::DCOPMeta[self.name] || KDE::DCOPMetaInfo.new(self)
+ meta.add_slots(slot_list)
+ meta.changed = true
+ end
+end
diff --git a/korundum/rubylib/korundum/lib/Makefile.am b/korundum/rubylib/korundum/lib/Makefile.am
new file mode 100644
index 00000000..fba7d258
--- /dev/null
+++ b/korundum/rubylib/korundum/lib/Makefile.am
@@ -0,0 +1 @@
+SUBDIRS = KDE