/*************************************************************************** * * * 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 #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "smoke.h" #undef DEBUG #ifndef _GNU_SOURCE #define _GNU_SOURCE #endif #ifndef __USE_POSIX #define __USE_POSIX #endif #ifndef __USE_XOPEN #define __USE_XOPEN #endif #include #include "marshall.h" #include "qtruby.h" #include "smokeruby.h" #ifndef HINT_BYTES #define HINT_BYTES HINT_BYTE #endif #define HAVE_STRLCAT_PROTO 1 #define HAVE_STRLCPY_PROTO 1 #include "config.h" #ifndef HAVE_RUBY_1_9 #define RARRAY_LEN(x) (RARRAY(x)->len) #define RSTRING_LEN(x) (RSTRING(x)->len) #define rb_str_catf_1 rb_str_catf #endif extern "C" { extern VALUE set_obj_info(const char * className, smokeruby_object * o); extern VALUE qt_internal_module; extern VALUE qvariant_class; extern bool application_terminated; }; extern bool isDerivedFromByName(Smoke *smoke, const char *className, const char *baseClassName); extern void mapPointer(VALUE obj, smokeruby_object *o, Smoke::Index classId, void *lastptr); static const char * (*_kde_resolve_classname)(Smoke*, int, void*) = 0; extern "C" { void set_kde_resolve_classname(const char * (*kde_resolve_classname) (Smoke*, int, void *)) { _kde_resolve_classname = kde_resolve_classname; } }; void mark_qobject_children(TQObject * qobject) { VALUE obj; const TQObjectList *l = qobject->children(); if (l == 0) { return; } TQObjectListIt it( *l ); // iterate over the children TQObject *child; while ( (child = it.current()) != 0 ) { ++it; obj = getPointerObject(child); if (obj != Qnil) { if(do_debug & qtdb_gc) tqWarning("Marking (%s*)%p -> %p\n", child->className(), child, (void*)obj); rb_gc_mark(obj); } mark_qobject_children(child); } } void smokeruby_mark(void * p) { VALUE obj; smokeruby_object * o = (smokeruby_object *) p; const char *className = o->smoke->classes[o->classId].className; if(do_debug & qtdb_gc) tqWarning("Checking for mark (%s*)%p\n", className, o->ptr); if(o->ptr && o->allocated) { if (isDerivedFromByName(o->smoke, className, "TQListView")) { TQListView * listview = (TQListView *) o->smoke->cast(o->ptr, o->classId, o->smoke->idClass("TQListView")); TQListViewItemIterator it(listview); TQListViewItem *item; while ( (item = it.current()) != 0 ) { ++it; obj = getPointerObject(item); if (obj != Qnil) { if(do_debug & qtdb_gc) tqWarning("Marking (%s*)%p -> %p\n", className, item, (void*)obj); rb_gc_mark(obj); } } return; } if (isDerivedFromByName(o->smoke, className, "TQTable")) { TQTable * table = (TQTable *) o->smoke->cast(o->ptr, o->classId, o->smoke->idClass("TQTable")); TQTableItem *item; for ( int row = 0; row < table->numRows(); row++ ) { for ( int col = 0; col < table->numCols(); col++ ) { item = table->item(row, col); obj = getPointerObject(item); if (obj != Qnil) { if(do_debug & qtdb_gc) tqWarning("Marking (%s*)%p -> %p\n", className, item, (void*)obj); rb_gc_mark(obj); } } } return; } if (isDerivedFromByName(o->smoke, className, "TQCanvas")) { TQCanvas * canvas = (TQCanvas *) o->smoke->cast(o->ptr, o->classId, o->smoke->idClass("TQCanvas")); TQCanvasItemList list = canvas->allItems(); for ( TQCanvasItemList::iterator it = list.begin(); it != list.end(); ++it ) { obj = getPointerObject(*it); if (obj != Qnil) { if(do_debug & qtdb_gc) tqWarning("Marking (%s*)%p -> %p\n", className, *it, (void*)obj); rb_gc_mark(obj); } } return; } if (isDerivedFromByName(o->smoke, className, "TQCanvasItem")) { TQCanvasItem * item = (TQCanvasItem *) o->smoke->cast(o->ptr, o->classId, o->smoke->idClass("TQCanvasItem")); TQCanvas * canvas = item->canvas(); obj = getPointerObject(canvas); if (obj != Qnil) { if(do_debug & qtdb_gc) tqWarning("Marking (%s*)%p -> %p\n", "TQCanvas", canvas, (void*)obj); rb_gc_mark(obj); } return; } if (isDerivedFromByName(o->smoke, className, "TQObject")) { TQObject * qobject = (TQObject *) o->smoke->cast(o->ptr, o->classId, o->smoke->idClass("TQObject")); mark_qobject_children(qobject); return; } } } void smokeruby_free(void * p) { smokeruby_object *o = (smokeruby_object*)p; const char *className = o->smoke->classes[o->classId].className; if(do_debug & qtdb_gc) tqWarning("Checking for delete (%s*)%p allocated: %s\n", className, o->ptr, o->allocated ? "true" : "false"); if(application_terminated || !o->allocated || o->ptr == 0) { free(o); return; } unmapPointer(o, o->classId, 0); object_count --; if ( tqstrcmp(className, "TQObject") == 0 || tqstrcmp(className, "TQListBoxItem") == 0 || tqstrcmp(className, "TQStyleSheetItem") == 0 || tqstrcmp(className, "KCommand") == 0 || tqstrcmp(className, "KNamedCommand") == 0 || tqstrcmp(className, "KMacroCommand") == 0 || tqstrcmp(className, "TDEAboutData") == 0 || tqstrcmp(className, "TDECmdLineArgs") == 0 || tqstrcmp(className, "TQSqlCursor") == 0 ) { // Don't delete instances of these classes for now free(o); return; } else if (isDerivedFromByName(o->smoke, className, "TQLayoutItem")) { TQLayoutItem * item = (TQLayoutItem *) o->smoke->cast(o->ptr, o->classId, o->smoke->idClass("TQLayoutItem")); if (item->layout() != 0 || item->widget() != 0 || item->spacerItem() != 0) { free(o); return; } } else if (tqstrcmp(className, "TQIconViewItem") == 0) { TQIconViewItem * item = (TQIconViewItem *) o->ptr; if (item->iconView() != 0) { free(o); return; } } else if (tqstrcmp(className, "TQCheckListItem") == 0) { TQCheckListItem * item = (TQCheckListItem *) o->ptr; if (item->parent() != 0 || item->listView() != 0) { free(o); return; } } else if (tqstrcmp(className, "TQListViewItem") == 0) { TQListViewItem * item = (TQListViewItem *) o->ptr; if (item->parent() != 0 || item->listView() != 0) { free(o); return; } } else if (isDerivedFromByName(o->smoke, className, "TQTableItem")) { TQTableItem * item = (TQTableItem *) o->smoke->cast(o->ptr, o->classId, o->smoke->idClass("TQTableItem")); if (item->table() != 0) { free(o); return; } } else if (tqstrcmp(className, "TQPopupMenu") == 0) { TQPopupMenu * item = (TQPopupMenu *) o->ptr; if (item->parentWidget(false) != 0) { free(o); return; } } else if (isDerivedFromByName(o->smoke, className, "TQWidget")) { TQWidget * qwidget = (TQWidget *) o->smoke->cast(o->ptr, o->classId, o->smoke->idClass("TQWidget")); if (qwidget->parentWidget(true) != 0) { free(o); return; } } else if (isDerivedFromByName(o->smoke, className, "TQObject")) { TQObject * qobject = (TQObject *) o->smoke->cast(o->ptr, o->classId, o->smoke->idClass("TQObject")); if (qobject->parent() != 0) { free(o); return; } } if(do_debug & qtdb_gc) tqWarning("Deleting (%s*)%p\n", className, o->ptr); char *methodName = new char[strlen(className) + 2]; methodName[0] = '~'; strcpy(methodName + 1, className); Smoke::Index nameId = o->smoke->idMethodName(methodName); Smoke::Index meth = o->smoke->findMethod(o->classId, nameId); if(meth > 0) { Smoke::Method &m = o->smoke->methods[o->smoke->methodMaps[meth].method]; Smoke::ClassFn fn = o->smoke->classes[m.classId].classFn; Smoke::StackItem i[1]; (*fn)(m.method, o->ptr, i); } delete[] methodName; free(o); return; } /* * Given an approximate classname and a qt instance, try to improve the resolution of the name * by using the various Qt rtti mechanisms for TQObjects, TQEvents and TQCanvasItems */ static const char * resolve_classname(Smoke* smoke, int classId, void * ptr) { if (isDerivedFromByName(smoke, smoke->classes[classId].className, "TQEvent")) { TQEvent * qevent = (TQEvent *) smoke->cast(ptr, classId, smoke->idClass("TQEvent")); switch (qevent->type()) { case TQEvent::ChildInserted: case TQEvent::ChildRemoved: return "TQt::ChildEvent"; case TQEvent::Close: return "TQt::CloseEvent"; case TQEvent::ContextMenu: return "TQt::ContextMenuEvent"; // case TQEvent::User: // return "TQt::CustomEvent"; case TQEvent::DragEnter: return "TQt::DragEnterEvent"; case TQEvent::DragLeave: return "TQt::DragLeaveEvent"; case TQEvent::DragMove: return "TQt::DragMoveEvent"; case TQEvent::DragResponse: return "TQt::DragResponseEvent"; case TQEvent::Drop: return "TQt::DropEvent"; case TQEvent::FocusIn: case TQEvent::FocusOut: return "TQt::FocusEvent"; case TQEvent::Hide: return "TQt::HideEvent"; case TQEvent::KeyPress: case TQEvent::KeyRelease: return "TQt::KeyEvent"; case TQEvent::IMStart: case TQEvent::IMCompose: case TQEvent::IMEnd: return "TQt::IMEvent"; case TQEvent::MouseButtonPress: case TQEvent::MouseButtonRelease: case TQEvent::MouseButtonDblClick: case TQEvent::MouseMove: return "TQt::MouseEvent"; case TQEvent::Move: return "TQt::MoveEvent"; case TQEvent::Paint: return "TQt::PaintEvent"; case TQEvent::Resize: return "TQt::ResizeEvent"; case TQEvent::Show: return "TQt::ShowEvent"; // case TQEvent::Tablet: // return "TQt::TabletEvent"; case TQEvent::Timer: return "TQt::TimerEvent"; case TQEvent::Wheel: return "TQt::WheelEvent"; default: break; } } else if (isDerivedFromByName(smoke, smoke->classes[classId].className, "TQObject")) { TQObject * qobject = (TQObject *) smoke->cast(ptr, classId, smoke->idClass("TQObject")); TQMetaObject * meta = qobject->metaObject(); while (meta != 0) { Smoke::Index classId = smoke->idClass(meta->className()); if (classId != 0) { return smoke->binding->className(classId); } meta = meta->superClass(); } } else if (isDerivedFromByName(smoke, smoke->classes[classId].className, "TQCanvasItem")) { TQCanvasItem * qcanvasitem = (TQCanvasItem *) smoke->cast(ptr, classId, smoke->idClass("TQCanvasItem")); switch (qcanvasitem->rtti()) { case TQCanvasItem::Rtti_Sprite: return "TQt::CanvasSprite"; case TQCanvasItem::Rtti_PolygonalItem: return "TQt::CanvasPolygonalItem"; case TQCanvasItem::Rtti_Text: return "TQt::CanvasText"; case TQCanvasItem::Rtti_Polygon: return "TQt::CanvasPolygon"; case TQCanvasItem::Rtti_Rectangle: return "TQt::CanvasRectangle"; case TQCanvasItem::Rtti_Ellipse: return "TQt::CanvasEllipse"; case TQCanvasItem::Rtti_Line: return "TQt::CanvasLine"; case TQCanvasItem::Rtti_Spline: return "TQt::CanvasSpline"; default: break; } } else if (isDerivedFromByName(smoke, smoke->classes[classId].className, "TQListViewItem")) { TQListViewItem * item = (TQListViewItem *) smoke->cast(ptr, classId, smoke->idClass("TQListViewItem")); switch (item->rtti()) { case 0: return "TQt::ListViewItem"; case 1: return "TQt::CheckListItem"; default: return "TQt::ListViewItem"; break; } } else if (isDerivedFromByName(smoke, smoke->classes[classId].className, "TQTableItem")) { TQTableItem * item = (TQTableItem *) smoke->cast(ptr, classId, smoke->idClass("TQTableItem")); switch (item->rtti()) { case 0: return "TQt::TableItem"; case 1: return "TQt::ComboTableItem"; case 2: return "TQt::CheckTableItem"; default: return "TQt::TableItem"; break; } } if (_kde_resolve_classname != 0) { return (*_kde_resolve_classname)(smoke, classId, ptr); } return smoke->binding->className(classId); } bool matches_arg(Smoke *smoke, Smoke::Index meth, Smoke::Index argidx, const char *argtype) { Smoke::Index *arg = smoke->argumentList + smoke->methods[meth].args + argidx; SmokeType type = SmokeType(smoke, *arg); return type.name() && tqstrcmp(type.name(), argtype) == 0; } void * construct_copy(smokeruby_object *o) { const char *className = o->smoke->className(o->classId); int classNameLen = strlen(className); char *ccSig = new char[classNameLen + 2]; // copy constructor signature strcpy(ccSig, className); strcat(ccSig, "#"); Smoke::Index ccId = o->smoke->idMethodName(ccSig); delete[] ccSig; char *ccArg = new char[classNameLen + 8]; sprintf(ccArg, "const %s&", className); Smoke::Index ccMeth = o->smoke->findMethod(o->classId, ccId); if(!ccMeth) { delete[] ccArg; return 0; } Smoke::Index method = o->smoke->methodMaps[ccMeth].method; if(method > 0) { // Make sure it's a copy constructor if(!matches_arg(o->smoke, method, 0, ccArg)) { delete[] ccArg; return 0; } delete[] ccArg; ccMeth = method; } else { // ambiguous method, pick the copy constructor Smoke::Index i = -method; while(o->smoke->ambiguousMethodList[i]) { if(matches_arg(o->smoke, o->smoke->ambiguousMethodList[i], 0, ccArg)) break; i++; } delete[] ccArg; ccMeth = o->smoke->ambiguousMethodList[i]; if(!ccMeth) return 0; } // Okay, ccMeth is the copy constructor. Time to call it. Smoke::StackItem args[2]; args[0].s_voidp = 0; args[1].s_voidp = o->ptr; Smoke::ClassFn fn = o->smoke->classes[o->classId].classFn; (*fn)(o->smoke->methods[ccMeth].method, 0, args); return args[0].s_voidp; } void marshall_basetype(Marshall *m) { switch(m->type().elem()) { case Smoke::t_bool: switch(m->action()) { case Marshall::FromVALUE: if (TYPE(*(m->var())) == T_OBJECT) { // A TQt::Boolean has been passed as a value VALUE temp = rb_funcall(qt_internal_module, rb_intern("get_qboolean"), 1, *(m->var())); m->item().s_bool = (temp == Qtrue ? true : false); } else { m->item().s_bool = (*(m->var()) == Qtrue ? true : false); } break; case Marshall::ToVALUE: *(m->var()) = m->item().s_bool ? Qtrue : Qfalse; break; default: m->unsupported(); break; } break; case Smoke::t_char: switch(m->action()) { case Marshall::FromVALUE: m->item().s_char = NUM2CHR(*(m->var())); break; case Marshall::ToVALUE: *(m->var()) = CHR2FIX(m->item().s_char); break; default: m->unsupported(); break; } break; case Smoke::t_uchar: switch(m->action()) { case Marshall::FromVALUE: m->item().s_uchar = NUM2CHR(*(m->var())); break; case Marshall::ToVALUE: *(m->var()) = CHR2FIX(m->item().s_uchar); break; default: m->unsupported(); break; } break; case Smoke::t_short: switch(m->action()) { case Marshall::FromVALUE: m->item().s_short = (short) NUM2INT(*(m->var())); break; case Marshall::ToVALUE: *(m->var()) = INT2NUM(m->item().s_short); break; default: m->unsupported(); break; } break; case Smoke::t_ushort: switch(m->action()) { case Marshall::FromVALUE: m->item().s_ushort = (unsigned short) NUM2UINT(*(m->var())); break; case Marshall::ToVALUE: *(m->var()) = UINT2NUM(m->item().s_ushort); break; default: m->unsupported(); break; } break; case Smoke::t_int: switch(m->action()) { case Marshall::FromVALUE: if (TYPE(*(m->var())) == T_OBJECT) { m->item().s_int = (int) NUM2INT(rb_funcall(qt_internal_module, rb_intern("get_qinteger"), 1, *(m->var()))); } else { m->item().s_int = (int) NUM2INT(*(m->var())); } break; case Marshall::ToVALUE: *(m->var()) = INT2NUM(m->item().s_int); break; default: m->unsupported(); break; } break; case Smoke::t_uint: switch(m->action()) { case Marshall::FromVALUE: if (TYPE(*(m->var())) == T_OBJECT) { m->item().s_int = (unsigned int) NUM2UINT(rb_funcall(qt_internal_module, rb_intern("get_qinteger"), 1, *(m->var()))); } else { m->item().s_uint = (unsigned int) NUM2UINT(*(m->var())); } break; case Marshall::ToVALUE: *(m->var()) = UINT2NUM(m->item().s_uint); break; default: m->unsupported(); break; } break; case Smoke::t_long: switch(m->action()) { case Marshall::FromVALUE: if (TYPE(*(m->var())) == T_OBJECT) { m->item().s_int = (long) NUM2LONG(rb_funcall(qt_internal_module, rb_intern("get_qinteger"), 1, *(m->var()))); } else { m->item().s_long = (long) NUM2LONG(*(m->var())); } break; case Marshall::ToVALUE: *(m->var()) = INT2NUM(m->item().s_long); break; default: m->unsupported(); break; } break; case Smoke::t_ulong: switch(m->action()) { case Marshall::FromVALUE: if (TYPE(*(m->var())) == T_OBJECT) { m->item().s_int = (unsigned long) NUM2ULONG(rb_funcall(qt_internal_module, rb_intern("get_qinteger"), 1, *(m->var()))); } else { m->item().s_ulong = (unsigned long) NUM2ULONG(*(m->var())); } break; case Marshall::ToVALUE: *(m->var()) = INT2NUM(m->item().s_ulong); break; default: m->unsupported(); break; } break; case Smoke::t_float: switch(m->action()) { case Marshall::FromVALUE: m->item().s_float = (float) NUM2DBL(*(m->var())); break; case Marshall::ToVALUE: *(m->var()) = rb_float_new((double) m->item().s_float); break; default: m->unsupported(); break; } break; case Smoke::t_double: switch(m->action()) { case Marshall::FromVALUE: m->item().s_double = (double) NUM2DBL(*(m->var())); break; case Marshall::ToVALUE: *(m->var()) = rb_float_new(m->item().s_double); break; default: m->unsupported(); break; } break; case Smoke::t_enum: switch(m->action()) { case Marshall::FromVALUE: { if (TYPE(*(m->var())) == T_OBJECT) { // A TQt::Enum is a subclass of TQt::Integer, so 'get_qinteger()' can be called ok VALUE temp = rb_funcall(qt_internal_module, rb_intern("get_qinteger"), 1, *(m->var())); m->item().s_enum = (long) NUM2LONG(temp); } else { m->item().s_enum = (long) NUM2LONG(*(m->var())); } } break; case Marshall::ToVALUE: *(m->var()) = rb_funcall( qt_internal_module, rb_intern("create_qenum"), 2, INT2NUM(m->item().s_enum), rb_str_new2(m->type().name()) ); break; default: m->unsupported(); break; } break; case Smoke::t_class: switch(m->action()) { case Marshall::FromVALUE: { if(*(m->var()) == Qnil) { m->item().s_class = 0; break; } if(TYPE(*(m->var())) != T_DATA) { rb_raise(rb_eArgError, "Invalid type, expecting %s\n", m->type().name()); break; } smokeruby_object *o = value_obj_info(*(m->var())); if(!o || !o->ptr) { if(m->type().isRef()) { rb_warning("References can't be nil\n"); m->unsupported(); } m->item().s_class = 0; break; } void *ptr = o->ptr; if(!m->cleanup() && m->type().isStack()) { ptr = construct_copy(o); } const Smoke::Class &c = m->smoke()->classes[m->type().classId()]; ptr = o->smoke->cast( ptr, // pointer o->classId, // from o->smoke->idClass(c.className) // to ); m->item().s_class = ptr; break; } break; case Marshall::ToVALUE: { if(m->item().s_voidp == 0) { *(m->var()) = Qnil; break; } void *p = m->item().s_voidp; VALUE obj = getPointerObject(p); if(obj != Qnil) { *(m->var()) = obj; break; } smokeruby_object * o = (smokeruby_object *) malloc(sizeof(smokeruby_object)); o->smoke = m->smoke(); o->classId = m->type().classId(); o->ptr = p; o->allocated = false; const char * classname = resolve_classname(o->smoke, o->classId, o->ptr); if(m->type().isConst() && m->type().isRef()) { p = construct_copy( o ); if(p) { o->ptr = p; o->allocated = true; } } obj = set_obj_info(classname, o); if (do_debug & qtdb_calls) { tqWarning("allocating %s %p -> %p\n", classname, o->ptr, (void*)obj); } if(m->type().isStack()) { o->allocated = true; // Keep a mapping of the pointer so that it is only wrapped once as a ruby VALUE mapPointer(obj, o, o->classId, 0); } *(m->var()) = obj; } break; default: m->unsupported(); break; } break; default: m->unsupported(); break; } } static void marshall_void(Marshall * /*m*/) {} static void marshall_unknown(Marshall *m) { m->unsupported(); } static void marshall_charP(Marshall *m) { switch(m->action()) { case Marshall::FromVALUE: { VALUE rv = *(m->var()); if (rv == Qnil) { m->item().s_voidp = 0; break; } int len = RSTRING_LEN(rv); char* mem = (char*) malloc(len+1); memcpy(mem, StringValuePtr(rv), len); mem[len] ='\0'; m->item().s_voidp = mem; } break; case Marshall::ToVALUE: { char *p = (char*)m->item().s_voidp; if(p) *(m->var()) = rb_str_new2(p); else *(m->var()) = Qnil; if(m->cleanup()) delete[] p; } break; default: m->unsupported(); break; } } void marshall_ucharP(Marshall *m) { switch(m->action()) { case Marshall::FromVALUE: { VALUE rv = *(m->var()); if (rv == Qnil) { m->item().s_voidp = 0; break; } int len = RSTRING_LEN(rv); char* mem = (char*) malloc(len+1); memcpy(mem, StringValuePtr(rv), len); mem[len] ='\0'; m->item().s_voidp = mem; } break; case Marshall::ToVALUE: default: m->unsupported(); break; } } static const char * KCODE = 0; static TQTextCodec *codec = 0; static void init_codec() { VALUE temp = rb_gv_get("$KCODE"); KCODE = StringValuePtr(temp); if (tqstrcmp(KCODE, "EUC") == 0) { codec = TQTextCodec::codecForName("eucJP"); } else if (tqstrcmp(KCODE, "SJIS") == 0) { codec = TQTextCodec::codecForName("Shift-JIS"); } } TQString* qstringFromRString(VALUE rstring) { if (KCODE == 0) { init_codec(); } TQString * s; if (tqstrcmp(KCODE, "UTF8") == 0) s = new TQString(TQString::fromUtf8(StringValuePtr(rstring), RSTRING_LEN(rstring))); else if (tqstrcmp(KCODE, "EUC") == 0) s = new TQString(codec->toUnicode(StringValuePtr(rstring))); else if (tqstrcmp(KCODE, "SJIS") == 0) s = new TQString(codec->toUnicode(StringValuePtr(rstring))); else if(tqstrcmp(KCODE, "NONE") == 0) s = new TQString(TQString::fromLatin1(StringValuePtr(rstring))); else s = new TQString(TQString::fromLocal8Bit(StringValuePtr(rstring), RSTRING_LEN(rstring))); return s; } VALUE rstringFromTQString(TQString * s) { if (KCODE == 0) { init_codec(); } if (tqstrcmp(KCODE, "UTF8") == 0) return rb_str_new2(s->utf8()); else if (tqstrcmp(KCODE, "EUC") == 0) return rb_str_new2(codec->fromUnicode(*s)); else if (tqstrcmp(KCODE, "SJIS") == 0) return rb_str_new2(codec->fromUnicode(*s)); else if (tqstrcmp(KCODE, "NONE") == 0) return rb_str_new2(s->latin1()); else return rb_str_new2(s->local8Bit()); } static void marshall_TQString(Marshall *m) { switch(m->action()) { case Marshall::FromVALUE: { TQString* s = 0; if ( *(m->var()) != Qnil) { s = qstringFromRString(*(m->var())); } else { s = new TQString(TQString::null); } m->item().s_voidp = s; m->next(); if (!m->type().isConst() && *(m->var()) != Qnil && s != 0 && !s->isNull()) { rb_str_resize(*(m->var()), 0); VALUE temp = rstringFromTQString(s); rb_str_cat2(*(m->var()), StringValuePtr(temp)); } if (s != 0 && m->cleanup()) { delete s; } } break; case Marshall::ToVALUE: { TQString *s = (TQString*)m->item().s_voidp; if (s != 0) { if (s->isNull()) { *(m->var()) = Qnil; } else { *(m->var()) = rstringFromTQString(s); } if (m->cleanup() || m->type().isStack()) { delete s; } } else { *(m->var()) = Qnil; } } break; default: m->unsupported(); break; } } // The only way to convert a TQChar to a TQString is to // pass a TQChar to a TQString constructor. However, // TQStrings aren't in the QtRuby api, so add this // convenience method 'TQt::Char.to_s' to get a ruby // string from a TQt::Char. VALUE qchar_to_s(VALUE self) { smokeruby_object *o = value_obj_info(self); if (o == 0 || o->ptr == 0) { return Qnil; } TQChar * qchar = (TQChar*) o->ptr; TQString s(*qchar); return rstringFromTQString(&s); } #if 0 static const char *not_ascii(const char *s, uint &len) { bool r = false; for(; *s ; s++, len--) if((uint)*s > 0x7F) { r = true; break; } return r ? s : 0L; } #endif static void marshall_TQCString(Marshall *m) { switch(m->action()) { case Marshall::FromVALUE: { TQCString *s = 0; VALUE rv = *(m->var()); if (rv == Qnil) { s = new TQCString(); } else { // Add 1 to the ruby string length to allow for a TQCString '\0' terminator s = new TQCString(StringValuePtr(*(m->var())), RSTRING_LEN(*(m->var())) + 1); } m->item().s_voidp = s; m->next(); if (!m->type().isConst() && rv != Qnil && s != 0) { rb_str_resize(rv, 0); rb_str_cat2(rv, (const char *)*s); } if(s && m->cleanup()) delete s; } break; case Marshall::ToVALUE: { TQCString *s = (TQCString*)m->item().s_voidp; if(s && (const char *) *s != 0) { *(m->var()) = rb_str_new2((const char *)*s); // const char * p = (const char *)*s; // uint len = s->length(); // if(not_ascii(p,len)) // { // #if PERL_VERSION == 6 && PERL_SUBVERSION == 0 // TQTextCodec* c = TQTextCodec::codecForMib(106); // utf8 // if(c->heuristicContentMatch(p,len) >= 0) // #else // if(is_utf8_string((U8 *)p,len)) // #endif // SvUTF8_on(*(m->var())); // } } else { if (m->type().isConst()) { *(m->var()) = Qnil; } else { *(m->var()) = rb_str_new2(""); } } m->next(); if (!m->type().isConst() && s != 0) { *s = (const char *) StringValuePtr(*(m->var())); } if(s && m->cleanup()) delete s; } break; default: m->unsupported(); break; } } static void marshall_TQCOORD_array(Marshall *m) { switch(m->action()) { case Marshall::FromVALUE: { VALUE av = *(m->var()); if (TYPE(av) != T_ARRAY) { m->item().s_voidp = 0; break; } int count = RARRAY_LEN(av); TQCOORD *coord = new TQCOORD[count + 2]; for(long i = 0; i < count; i++) { VALUE svp = rb_ary_entry(av, i); coord[i] = NUM2INT(svp); } m->item().s_voidp = coord; m->next(); } break; default: m->unsupported(); } } static void marshall_longlong(Marshall *m) { switch(m->action()) { case Marshall::FromVALUE: { m->item().s_voidp = new long long; *(long long *)m->item().s_voidp = rb_num2ll(*(m->var())); m->next(); if(m->cleanup() && m->type().isConst()) { delete (long long *) m->item().s_voidp; } } break; case Marshall::ToVALUE: { *(m->var()) = rb_ll2inum(*(long long *) m->item().s_voidp); } break; default: m->unsupported(); break; } } static void marshall_ulonglong(Marshall *m) { switch(m->action()) { case Marshall::FromVALUE: { m->item().s_voidp = new unsigned long long; *(long long *)m->item().s_voidp = rb_num2ull(*(m->var())); m->next(); if(m->cleanup() && m->type().isConst()) { delete (unsigned long long *) m->item().s_voidp; } } break; case Marshall::ToVALUE: { *(m->var()) = rb_ull2inum(*(unsigned long long *) m->item().s_voidp); } break; default: m->unsupported(); break; } } static void marshall_intR(Marshall *m) { switch(m->action()) { case Marshall::FromVALUE: { VALUE rv = *(m->var()); int * i = new int; if (TYPE(rv) == T_OBJECT) { // A TQt::Integer has been passed as an integer value VALUE temp = rb_funcall(qt_internal_module, rb_intern("get_qinteger"), 1, rv); *i = NUM2INT(temp); m->item().s_voidp = i; m->next(); rb_funcall(qt_internal_module, rb_intern("set_qinteger"), 2, rv, INT2NUM(*i)); rv = temp; } else { *i = NUM2INT(rv); m->item().s_voidp = i; m->next(); } if(m->cleanup() && m->type().isConst()) { delete i; } else { m->item().s_voidp = new int((int)NUM2INT(rv)); } } break; case Marshall::ToVALUE: { int *ip = (int*)m->item().s_voidp; VALUE rv = *(m->var()); if(!ip) { rv = Qnil; break; } *(m->var()) = INT2NUM(*ip); m->next(); if(!m->type().isConst()) *ip = NUM2INT(*(m->var())); } break; default: m->unsupported(); break; } } static void marshall_boolR(Marshall *m) { switch(m->action()) { case Marshall::FromVALUE: { VALUE rv = *(m->var()); bool * b = new bool; if (TYPE(rv) == T_OBJECT) { // A TQt::Boolean has been passed as a value VALUE temp = rb_funcall(qt_internal_module, rb_intern("get_qboolean"), 1, rv); *b = (temp == Qtrue ? true : false); m->item().s_voidp = b; m->next(); rb_funcall(qt_internal_module, rb_intern("set_qboolean"), 2, rv, (*b ? Qtrue : Qfalse)); } else { *b = (rv == Qtrue ? true : false); m->item().s_voidp = b; m->next(); } if(m->cleanup() && m->type().isConst()) { delete b; } } break; case Marshall::ToVALUE: { bool *ip = (bool*)m->item().s_voidp; if(!ip) { *(m->var()) = Qnil; break; } *(m->var()) = (*ip?Qtrue:Qfalse); m->next(); if(!m->type().isConst()) *ip = *(m->var()) == Qtrue ? true : false; } break; default: m->unsupported(); break; } } static void marshall_charP_array(Marshall *m) { switch(m->action()) { case Marshall::FromVALUE: { VALUE arglist = *(m->var()); if (arglist == Qnil || TYPE(arglist) != T_ARRAY || RARRAY_LEN(arglist) == 0 ) { m->item().s_voidp = 0; break; } char **argv = new char *[RARRAY_LEN(arglist) + 1]; long i; for(i = 0; i < RARRAY_LEN(arglist); i++) { VALUE item = rb_ary_entry(arglist, i); char *s = StringValuePtr(item); argv[i] = new char[strlen(s) + 1]; strcpy(argv[i], s); } argv[i] = 0; m->item().s_voidp = argv; m->next(); if(m->cleanup()) { rb_ary_clear(arglist); for(i = 0; argv[i]; i++) rb_ary_push(arglist, rb_str_new2(argv[i])); } } break; default: m->unsupported(); break; } } void marshall_TQStringList(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_LEN(list); TQStringList *stringlist = new TQStringList; for(long i = 0; i < count; i++) { VALUE item = rb_ary_entry(list, i); if(TYPE(item) != T_STRING) { stringlist->append(TQString()); continue; } stringlist->append(*(qstringFromRString(item))); } m->item().s_voidp = stringlist; m->next(); if (stringlist != 0 && !m->type().isConst()) { rb_ary_clear(list); for(TQStringList::Iterator it = stringlist->begin(); it != stringlist->end(); ++it) rb_ary_push(list, rstringFromTQString(&(*it))); } if (m->cleanup()) delete stringlist; break; } case Marshall::ToVALUE: { TQStringList *stringlist = static_cast(m->item().s_voidp); if(!stringlist) { *(m->var()) = Qnil; break; } VALUE av = rb_ary_new(); for(TQStringList::Iterator it = stringlist->begin(); it != stringlist->end(); ++it) { VALUE rv = rstringFromTQString(&(*it)); rb_ary_push(av, rv); } if(m->cleanup()) delete stringlist; *(m->var()) = av; } break; default: m->unsupported(); break; } } void marshall_TQStrList(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_LEN(list); TQStrList *stringlist = new TQStrList; for(long i = 0; i < count; i++) { VALUE item = rb_ary_entry(list, i); if(TYPE(item) != T_STRING) { stringlist->append(TQString()); continue; } stringlist->append(TQString::fromUtf8(StringValuePtr(item), RSTRING_LEN(item))); } m->item().s_voidp = stringlist; m->next(); if (!m->type().isConst()) { rb_ary_clear(list); for(const char * it = stringlist->first(); it != 0; it = stringlist->next()) rb_ary_push(list, rb_str_new2(it)); } if (m->cleanup()) { delete stringlist; } break; } case Marshall::ToVALUE: { TQStrList *stringlist = static_cast(m->item().s_voidp); if(!stringlist) { *(m->var()) = Qnil; break; } VALUE av = rb_ary_new(); for(const char * it = stringlist->first(); it != 0; it = stringlist->next()) { VALUE rv = rb_str_new2(it); rb_ary_push(av, rv); } if(m->cleanup()) delete stringlist; *(m->var()) = av; } break; default: m->unsupported(); break; } } template 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_LEN(list); 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->type().isConst()) { rb_ary_clear(list); for(ItemListIterator it = cpplist->begin(); it != cpplist->end(); ++it ) { VALUE obj = getPointerObject((void*)(*it)); rb_ary_push(list, obj); } } if (m->cleanup()) { delete cpplist; } } break; case Marshall::ToVALUE: { ItemList *valuelist = (ItemList*)m->item().s_voidp; if(!valuelist) { *(m->var()) = Qnil; break; } VALUE av = rb_ary_new(); 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 = m->smoke()->idClass(ItemSTR); o->ptr = p; o->allocated = false; obj = set_obj_info(resolve_classname(o->smoke, o->classId, o->ptr), o); } rb_ary_push(av, obj); } if(m->cleanup()) delete valuelist; else *(m->var()) = av; } break; default: m->unsupported(); break; } } void marshall_TQValueListInt(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_LEN(list); TQValueList *valuelist = new TQValueList; 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(NUM2INT(item)); } m->item().s_voidp = valuelist; m->next(); if (!m->type().isConst()) { rb_ary_clear(list); for(TQValueListIterator it = valuelist->begin(); it != valuelist->end(); ++it) rb_ary_push(list, INT2NUM((int)*it)); } if (m->cleanup()) { delete valuelist; } } break; case Marshall::ToVALUE: { TQValueList *valuelist = (TQValueList*)m->item().s_voidp; if(!valuelist) { *(m->var()) = Qnil; break; } VALUE av = rb_ary_new(); for(TQValueListIterator it = valuelist->begin(); it != valuelist->end(); ++it) rb_ary_push(av, INT2NUM(*it)); *(m->var()) = av; if(m->cleanup()) delete valuelist; } break; default: m->unsupported(); break; } } void marshall_voidP(Marshall *m) { switch(m->action()) { case Marshall::FromVALUE: { VALUE rv = *(m->var()); if (rv != Qnil) m->item().s_voidp = (void*)NUM2INT(*(m->var())); else m->item().s_voidp = 0; } break; case Marshall::ToVALUE: { *(m->var()) = Data_Wrap_Struct(rb_cObject, 0, 0, m->item().s_voidp); } break; default: m->unsupported(); break; } } void marshall_TQMapTQStringTQString(Marshall *m) { switch(m->action()) { case Marshall::FromVALUE: { VALUE hash = *(m->var()); if (TYPE(hash) != T_HASH) { m->item().s_voidp = 0; break; } TQMap * map = new TQMap; // 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_LEN(temp); i++) { VALUE key = rb_ary_entry(rb_ary_entry(temp, i), 0); VALUE value = rb_ary_entry(rb_ary_entry(temp, i), 1); (*map)[TQString(StringValuePtr(key))] = TQString(StringValuePtr(value)); } m->item().s_voidp = map; m->next(); if(m->cleanup()) delete map; } break; case Marshall::ToVALUE: { TQMap *map = (TQMap*)m->item().s_voidp; if(!map) { *(m->var()) = Qnil; break; } VALUE hv = rb_hash_new(); TQMap::Iterator it; for (it = map->begin(); it != map->end(); ++it) { rb_hash_aset(hv, rstringFromTQString((TQString*)&(it.key())), rstringFromTQString((TQString*) &(it.data()))); } *(m->var()) = hv; m->next(); if(m->cleanup()) delete map; } break; default: m->unsupported(); break; } } void marshall_TQMapTQStringTQVariant(Marshall *m) { switch(m->action()) { case Marshall::FromVALUE: { VALUE hash = *(m->var()); if (TYPE(hash) != T_HASH) { m->item().s_voidp = 0; break; } TQMap * map = new TQMap; // 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_LEN(temp); 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 || o->classId != o->smoke->idClass("TQVariant")) { // If the value isn't a TQt::Variant, then try and construct // a TQt::Variant from it value = rb_funcall(qvariant_class, rb_intern("new"), 1, value); if (value == Qnil) { continue; } o = value_obj_info(value); } void * ptr = o->ptr; ptr = o->smoke->cast(ptr, o->classId, o->smoke->idClass("TQVariant")); (*map)[TQString(StringValuePtr(key))] = (TQVariant)*(TQVariant*)ptr; } m->item().s_voidp = map; m->next(); if(m->cleanup()) delete map; } break; case Marshall::ToVALUE: { TQMap *map = (TQMap*)m->item().s_voidp; if(!map) { *(m->var()) = Qnil; break; } VALUE hv = rb_hash_new(); TQMap::Iterator it; for (it = map->begin(); it != map->end(); ++it) { void *p = new TQVariant(it.data()); VALUE obj = getPointerObject(p); if (obj == Qnil) { smokeruby_object * o = ALLOC(smokeruby_object); o->classId = m->smoke()->idClass("TQVariant"); o->smoke = m->smoke(); o->ptr = p; o->allocated = true; obj = set_obj_info("TQt::Variant", o); } rb_hash_aset(hv, rstringFromTQString((TQString*)&(it.key())), obj); } *(m->var()) = hv; m->next(); if(m->cleanup()) delete map; } break; default: m->unsupported(); break; } } void marshall_TQUObject(Marshall *m) { switch(m->action()) { case Marshall::FromVALUE: { VALUE array = *(m->var()); if (array != Qnil && TYPE(array) == T_ARRAY) { VALUE rv = rb_ary_entry(array, 0); Data_Get_Struct(rv, TQUObject, m->item().s_voidp); } else { m->item().s_voidp = 0; } } break; case Marshall::ToVALUE: { VALUE rv = Data_Wrap_Struct(rb_cObject, 0, 0, m->item().s_voidp); VALUE array = rb_ary_new2(1); rb_ary_push(array, rv); *(m->var()) = array; } break; default: m->unsupported(); break; } } void marshall_TQRgb_array(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_LEN(list); TQRgb *rgb = new TQRgb[count + 2]; long i; for(i = 0; i < count; i++) { VALUE item = rb_ary_entry(list, i); if(TYPE(item) != T_FIXNUM && TYPE(item) != T_BIGNUM) { rgb[i] = 0; continue; } rgb[i] = NUM2UINT(item); } m->item().s_voidp = rgb; m->next(); } break; case Marshall::ToVALUE: // Implement this with a tied array or something default: m->unsupported(); break; } } void marshall_TQPairintint(Marshall *m) { switch(m->action()) { case Marshall::FromVALUE: { VALUE list = *(m->var()); if (TYPE(list) != T_ARRAY || RARRAY_LEN(list) != 2) { m->item().s_voidp = 0; break; } int int0; int int1; VALUE item = rb_ary_entry(list, 0); if(TYPE(item) != T_FIXNUM && TYPE(item) != T_BIGNUM) { int0 = 0; } else { int0 = NUM2INT(item); } item = rb_ary_entry(list, 1); if(TYPE(item) != T_FIXNUM && TYPE(item) != T_BIGNUM) { int1 = 0; } else { int1 = NUM2INT(item); } TQPair * qpair = new TQPair(int0,int1); m->item().s_voidp = qpair; m->next(); if(m->cleanup()) delete qpair; } break; case Marshall::ToVALUE: default: m->unsupported(); break; } } #define DEF_LIST_MARSHALLER(ListIdent,ItemList,Item,Itr) namespace { char ListIdent##STR[] = #Item; }; \ Marshall::HandlerFn marshall_##ListIdent = marshall_ItemList; #include #include #include #include #include #include #include #include #if TQT_VERSION >= 0x030200 DEF_LIST_MARSHALLER( TQPtrListTQNetworkOperation, TQPtrList, TQNetworkOperation, TQPtrListStdIterator ) DEF_LIST_MARSHALLER( TQPtrListTQToolBar, TQPtrList, TQToolBar, TQPtrListStdIterator ) DEF_LIST_MARSHALLER( TQPtrListTQTab, TQPtrList, TQTab, TQPtrListStdIterator ) DEF_LIST_MARSHALLER( TQPtrListTQDockWindow, TQPtrList, TQDockWindow, TQPtrListStdIterator ) DEF_LIST_MARSHALLER( TQFileInfoList, TQFileInfoList, TQFileInfo, TQFileInfoList::Iterator ) DEF_LIST_MARSHALLER( TQObjectList, TQObjectList, TQObject, TQPtrListStdIterator ) DEF_LIST_MARSHALLER( TQWidgetList, TQWidgetList, TQWidget, TQPtrListStdIterator ) #endif DEF_LIST_MARSHALLER( TQCanvasItemList, TQCanvasItemList, TQCanvasItem, TQValueListIterator ) template 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_LEN(list); 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); // Special case for the TQValueList type if ( tqstrcmp(ItemSTR, "TQVariant") == 0 && (!o || !o->ptr || o->classId != o->smoke->idClass("TQVariant")) ) { // If the value isn't a TQt::Variant, then try and construct // a TQt::Variant from it item = rb_funcall(qvariant_class, rb_intern("new"), 1, item); if (item == Qnil) { continue; } 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->type().isConst()) { rb_ary_clear(list); for(ItemListIterator it = cpplist->begin(); it != cpplist->end(); ++it) { VALUE obj = getPointerObject((void*)&(*it)); rb_ary_push(list, obj); } } if (m->cleanup()) { 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 dummy { char ListIdent##STR[] = #Item; }; \ Marshall::HandlerFn marshall_##ListIdent = marshall_ValueItemList; DEF_VALUELIST_MARSHALLER( TQVariantList, TQValueList, TQVariant, TQValueList::Iterator ) DEF_VALUELIST_MARSHALLER( TQPixmapList, TQValueList, TQPixmap, TQValueList::Iterator ) DEF_VALUELIST_MARSHALLER( TQIconDragItemList, TQValueList, TQIconDragItem, TQValueList::Iterator ) DEF_VALUELIST_MARSHALLER( TQImageTextKeyLangList, TQValueList, TQImageTextKeyLang, TQValueList::Iterator ) DEF_VALUELIST_MARSHALLER( TQUrlInfoList, TQValueList, TQUrlInfo, TQValueList::Iterator ) DEF_VALUELIST_MARSHALLER( TQTranslatorMessageList, TQValueList, TQTranslatorMessage, TQValueList::Iterator ) DEF_VALUELIST_MARSHALLER( TQHostAddressList, TQValueList, TQHostAddress, TQValueList::Iterator ) TypeHandler Qt_handlers[] = { { "TQString", marshall_TQString }, { "TQString&", marshall_TQString }, { "TQString*", marshall_TQString }, { "TQCString", marshall_TQCString }, { "TQCString&", marshall_TQCString }, { "TQCString*", marshall_TQCString }, { "TQStringList", marshall_TQStringList }, { "TQStringList&", marshall_TQStringList }, { "TQStringList*", marshall_TQStringList }, { "TQStrList", marshall_TQStrList }, { "TQStrList&", marshall_TQStrList }, { "TQStrList*", marshall_TQStrList }, { "long long int", marshall_longlong }, { "long long int&", marshall_longlong }, { "TQ_INT64", marshall_longlong }, { "TQ_INT64&", marshall_longlong }, { "TQ_LLONG", marshall_longlong }, { "TQ_LLONG&", marshall_longlong }, { "TDEIO::filesize_t", marshall_longlong }, { "DOM::DOMTimeStamp", marshall_ulonglong }, { "unsigned long long int", marshall_ulonglong }, { "unsigned long long int&", marshall_ulonglong }, { "TQ_UINT64", marshall_ulonglong }, { "TQ_UINT64&", marshall_ulonglong }, { "TQ_ULLONG", marshall_ulonglong }, { "TQ_ULLONG&", marshall_ulonglong }, { "signed int&", marshall_intR }, { "int&", marshall_intR }, { "int*", marshall_intR }, { "bool&", marshall_boolR }, { "bool*", marshall_boolR }, { "char*", marshall_charP }, { "char**", marshall_charP_array }, { "uchar*", marshall_ucharP }, { "TQRgb*", marshall_TQRgb_array }, { "TQPair&", marshall_TQPairintint }, { "TQUObject*", marshall_TQUObject }, { "const TQCOORD*", marshall_TQCOORD_array }, { "void", marshall_void }, { "TQValueList", marshall_TQValueListInt }, { "TQValueList&", marshall_TQValueListInt }, { "TQValueList", marshall_TQVariantList }, { "TQValueList&", marshall_TQVariantList }, { "TQValueList", marshall_TQPixmapList }, { "TQValueList&", marshall_TQIconDragItemList }, { "TQValueList", marshall_TQImageTextKeyLangList }, { "TQValueList&", marshall_TQUrlInfoList }, { "TQValueList", marshall_TQTranslatorMessageList }, { "TQValueList", marshall_TQHostAddressList }, { "TQCanvasItemList", marshall_TQCanvasItemList }, { "TQMap", marshall_TQMapTQStringTQString }, { "TQMap&", marshall_TQMapTQStringTQString }, { "TQMap", marshall_TQMapTQStringTQVariant }, { "TQMap&", marshall_TQMapTQStringTQVariant }, #if TQT_VERSION >= 0x030200 { "TQWidgetList", marshall_TQWidgetList }, { "TQWidgetList*", marshall_TQWidgetList }, { "TQWidgetList&", marshall_TQWidgetList }, { "TQObjectList*", marshall_TQObjectList }, { "TQObjectList&", marshall_TQObjectList }, { "TQFileInfoList*", marshall_TQFileInfoList }, { "TQPtrList", marshall_TQPtrListTQToolBar }, { "TQPtrList*", marshall_TQPtrListTQTab }, { "TQPtrList", marshall_TQPtrListTQDockWindow }, { "TQPtrList*", marshall_TQPtrListTQDockWindow }, { "TQPtrList", marshall_TQPtrListTQNetworkOperation }, { "TQPtrList&", marshall_TQPtrListTQNetworkOperation }, #endif { 0, 0 } }; TQAsciiDict type_handlers(199); void install_handlers(TypeHandler *h) { while(h->name) { type_handlers.insert(h->name, h); h++; } } Marshall::HandlerFn getMarshallFn(const SmokeType &type) { if(type.elem()) return marshall_basetype; if(!type.name()) return marshall_void; TypeHandler *h = type_handlers[type.name()]; if(h == 0 && type.isConst() && strlen(type.name()) > strlen("const ")) { h = type_handlers[type.name() + strlen("const ")]; } if(h != 0) { return h->fn; } return marshall_unknown; }