/* * XS functions for /Qt::(signals|slots)::import/ * * Copyright (C) 1999, Ashley Winters * * You may distribute under the terms of the LGPL as specified in the * README.LICENSE file which should be included with this library. * */ #include "pig.h" #include #include #include #include "pigperl.h" #include "pigfunc_base.h" #include "pigfunc_object.h" #include "pigtype_object.h" #include "pigsigslot.h" HV *__pig_class_info = 0; class pig_public_QObject : public QObject { public: QConnectionList *getReceivers(const char *pig0) const { return receivers(pig0); } }; SV *pig_map_signal(const char *pigclass, const char *pigmethod) { static const char pigmap[] = ".signalmap"; char *pigvar; pigvar = new char [strlen(pigclass) + 2 + strlen(pigmap) + 1]; sprintf(pigvar, "%s::%s", pigclass, pigmap); HV *pigmaphv = perl_get_hv(pigvar, TRUE); //printf("getting %s::%s = %p\n", pigclass, pigmap, pigmaphv); delete [] pigvar; SV **pigsvp = hv_fetch(pigmaphv, (char *)pigmethod, strlen(pigmethod), 0); //printf("x = %p\n", pigsvp); //printf("foo = %s\n", SvPV(*pigsvp, na)); if(pigsvp) return *pigsvp; return &PIGsv_undef; } int pig_sigslot_typeidx(char pig1); void pig_pop_signal_arguments(const char *pigcrypt); typedef void (*pig_signal)(); extern pig_signal pig_signal_matrix[]; extern int pig_sigslot_exp_table[]; extern QObject *pig_signal_object; extern QMember *pig_signal_member; extern "C" PIG_PROTO(pig_signal_emit) { PIG_BEGIN(pig_emit); STRLEN n_a; const char *pigclass = HvNAME(GvSTASH(CvGV((CV *)pigCV))); const char *pigmethod = GvNAME(CvGV((CV *)pigCV)); SV *pigprotosv = pig_map_signal(pigclass, pigmethod); const char *pigproto = SvPV(pigprotosv, n_a); SV *pigcryptsv = pig_map_proto(pigprotosv); const char *pigcrypt = SvPV(pigcryptsv, n_a); QObject *pigobj = (QObject *)pig_type_object_argument("QObject"); //printf("Object = %p\n", pigobj); pig_pop_signal_arguments(pigcrypt); PIG_END_ARGUMENTS; pig_signal pig_hash_table[PIG_SIGSLOT_MAX_ARGS + 1]; pig_hash_table[0] = pig_signal_matrix[0]; { pig_sigslot_argument_iterator pigiter(pigcrypt); const char *pigarg; int pigi; long pigtot = 0; for(pigi = 1; pigi <= *pigcrypt; pigi++) { pigarg = ++pigiter; pigtot += pig_sigslot_exp_table[*pigcrypt - pigi] * pig_sigslot_typeidx(*pigarg); pig_hash_table[pigi] = pig_signal_matrix[pigtot]; } } QConnectionList *pigclist = ((pig_public_QObject *)pigobj)->getReceivers(pigproto); if(pigclist && !pigobj->signalsBlocked()) { QConnectionListIt pigit(*pigclist); QConnection *pigc; while((pigc = pigit.current())) { ++pigit; pig_signal_object = pigc->object(); pig_signal_member = pigc->member(); ((QSenderObject *)pig_signal_object)->setSender(pigobj); (*pig_hash_table[pigc->numArgs()])(); } } pig_return_nothing(); PIG_END; } static XS(PIG_Qt__signals_emit) { dXSARGS; XSRETURN_EMPTY; } extern "C" XS(PIG_Qt__signals_import) { dXSARGS; STRLEN n_a; static const char pigname[] = ".signals"; static const char pigmap[] = ".signalmap"; static const char pigemit[] = "emit"; const char *pigclass = HvNAME(PIGcurcop->cop_stash); if(items <= 1) XSRETURN_EMPTY; char *pigvar; pigvar = new char [strlen(pigclass) + 2 + strlen(pigname) + strlen(pigmap) + strlen(pigemit) + 1]; sprintf(pigvar, "%s::%s", pigclass, pigemit); newXS((char *)pigvar, PIG_Qt__signals_emit, (char *)__FILE__); sprintf(pigvar, "%s::%s", pigclass, pigname); HV *pighv = perl_get_hv(pigvar, TRUE); sprintf(pigvar, "%s::%s", pigclass, pigmap); HV *pigmaphv = perl_get_hv(pigvar, TRUE); delete [] pigvar; I32 pigx; for(pigx = 1; pigx < items; pigx++) { SV *pigsv, *pigcryptsv; const char *pigproto, *pigcrypt; char *pignewxs; pigsv = pig_parse_proto(ST(pigx)); pigcryptsv = pig_map_proto(pigsv); pigproto = SvPV(pigsv, n_a); pigcrypt = SvPV(pigcryptsv, n_a); hv_store(pighv, (char *)pigproto, SvCUR(pigsv), newSVsv(pigcryptsv), 0); hv_store(pigmaphv, (char *)pigcrypt + 2, strlen(pigcrypt + 2), newSVsv(pigsv), 0); pignewxs = new char [ strlen(pigclass) + 2 + strlen(pigcrypt + 2) + 1 ]; sprintf(pignewxs, "%s::%s", pigclass, pigcrypt + 2); // printf("newxs %s\n", pignewxs); newXS((char *)pignewxs, (XS((*)))pig_signal_emit, (char *)__FILE__); delete [] pignewxs; } } extern "C" XS(PIG_Qt__slots_import) { dXSARGS; STRLEN n_a; static const char pigname[] = ".slots"; const char *pigclass = HvNAME(PIGcurcop->cop_stash); if(items <= 1) XSRETURN_EMPTY; char *pigvar; pigvar = new char [strlen(pigclass) + 2 + strlen(pigname) + 1]; sprintf(pigvar, "%s::%s", pigclass, pigname); HV *pighv = perl_get_hv(pigvar, TRUE); delete [] pigvar; I32 pigx; for(pigx = 1; pigx < items; pigx++) { SV *pigsv; pigsv = pig_parse_proto(ST(pigx)); hv_store(pighv, SvPV(pigsv, n_a), SvCUR(pigsv), newSVsv(pig_map_proto(pigsv)), 0); } }