/**************************** Function: PutStr Vector: 158 Offset: -948 Arguments: D1.L pointer to string Returns: D0.L result code 0=OK, -1=Error ****************************/ int lib_dos_f_PutStr(emumsg_syscall_t *msg) { cpu_t *cpu; uint8_t *sptr; DEBUG(4) dprintf("dos.library: lib_dos_f_PutStr() called\n"); cpu = msg->proc->cpu; DEBUG(5) dprintf(" String (D1): 0x%x\n",cpu->d[1]); if(cpu->d[1] == 0) { DEBUG(1) dprintf("Warning: dos.library: lib_dos_f_PutStr() called with NULL string, skipping\n"); return HOOK_DONE; } /* TODO: Implement some kind of check for MMU entry ending within the string */ sptr = vptr(cpu->d[1]); DEBUG(5) dprintf(" String (native): %p\n",sptr); /* Prepare syscall */ msg->arg[0]._strptr = (STRPTR)sptr; return HOOK_SYSCALL; }
/**************************** Function: OpenLocale Vector: 26 Offset: -156 Arguments: A0.L locale name string Returns: D0.L pointer to struct Locale ****************************/ int lib_locale_f_OpenLocale(emumsg_syscall_t *msg) { cpu_t *cpu; uint8_t *string_real; DEBUG(4) dprintf("locale.library: lib_locale_f_OpenLocale() called\n"); cpu = msg->proc->cpu; DEBUG(5) dprintf(" Name (A0): 0x%x\n",cpu->a[0]); if(cpu->a[0] == 0) { string_real = NULL; } else { string_real = vptr(cpu->a[0]); if(string_real == NULL) { DEBUG(1) dprintf("Error: locale.library: lib_locale_f_OpenLocale: Locale name string pointer is invalid\n"); return HOOK_END_PROC; } } /* Prepare syscall */ msg->arg[0]._strptr = (STRPTR)string_real; DEBUG(5) dprintf(" Name (native): %p\n",string_real); /* Do syscall */ return HOOK_SYSCALL; }
void AIDA_Cloud1DIterator::fillData(const std::vector<iAIDA::AIDA_Function::AIDA_RangeSet * > & ranges) { int n = ranges.size(); if (n != m_dim) { INFO_MSG(" AIDA_Cloud1DIterator::fillData invalid dimension for rangeset - cannot feed data in FNL"); return; } if (!ranges[0]) { INFO_MSG(" AIDA_Cloud1DIterator::fillData invalid rangeset - cannot feed data in FNL"); return; } std::auto_ptr<fml::DataVector> vptr (new fml::DataVector()); std::vector<double> x(m_dim); int nPoints = 0; for(int i = 0; i<m_hist->entries(); ++i) { x[0] = m_hist->value(i); if (ranges[0]->isInRange(x[0]) ) { vptr->push_back(x, m_hist->weight(i), 0 ); //cout << " push in event " << x[0] << endl; nPoints++; } } // set the range (size is number of events !) - needed by FML vptr->setRange(fml::DataRange(nPoints) ); setVector(vptr); }
AJFunction::~AJFunction() { ASSERT(vptr() == AJGlobalData::jsFunctionVPtr); // JIT code for other functions may have had calls linked directly to the code for this function; these links // are based on a check for the this pointer value for this AJFunction - which will no longer be valid once // this memory is freed and may be reused (potentially for another, different AJFunction). if (!isHostFunction()) { #if ENABLE(JIT_OPTIMIZE_CALL) ASSERT(m_executable); if (jsExecutable()->isGenerated()) jsExecutable()->generatedBytecode().unlinkCallers(); #endif scopeChain().~ScopeChain(); // FIXME: Don't we need to do this in the interpreter too? } }
JSFunction::~JSFunction() { ASSERT(vptr() == JSGlobalData::jsFunctionVPtr); // JIT code for other functions may have had calls linked directly to the code for this function; these links // are based on a check for the this pointer value for this JSFunction - which will no longer be valid once // this memory is freed and may be reused (potentially for another, different JSFunction). if (!isHostFunction()) { #if ENABLE(JIT_OPTIMIZE_CALL) ASSERT(m_executable); if (jsExecutable()->isGeneratedForCall()) jsExecutable()->generatedBytecodeForCall().unlinkCallers(); if (jsExecutable()->isGeneratedForConstruct()) jsExecutable()->generatedBytecodeForConstruct().unlinkCallers(); #endif } }
void AIDA_Profile2DIterator::fillData(const std::vector<iAIDA::AIDA_Function::AIDA_RangeSet * > & ranges ) { int n = ranges.size(); if (n != m_dim) { INFO_MSG(" AIDA_Profile2DIterator::fillData invalid dimension for rangeset - cannot feed data in FNL"); return; } if (!ranges[0]) { INFO_MSG(" AIDA_Profile2DIterator::fillData invalid rangeset - cannot feed data in FNL"); return; } if (xIndex >= m_dim || yIndex >= m_dim) { INFO_MSG(" AIDA_Profile2DIterator::fillData invalid indices - cannot feed data in FNL"); return; } std::auto_ptr<fml::DataVector> vptr (new fml::DataVector()); std::vector<double> x(m_dim); int nPoints = 0; for(int i = 0; i<m_hist->xAxis().bins(); ++i) { for(int j = 0; j<m_hist->yAxis().bins(); ++j) { x[xIndex] = m_hist->binMeanX(i,j); x[yIndex] = m_hist->binMeanY(i,j); if (ranges[0]->isInRange(x[0]) && ranges[1]->isInRange(x[1])) { vptr->push_back(x, m_hist->binHeight(i,j), m_hist->binError(i,j) ); nPoints++; } } } // set the FML range (size is number of points in range) vptr->setRange(fml::DataRange( nPoints )); setVector(vptr); }
void tst_QSharedPointer::constCorrectness() { { QSharedPointer<Data> ptr = QSharedPointer<Data>(new Data); QSharedPointer<const Data> cptr(ptr); QSharedPointer<volatile Data> vptr(ptr); cptr = ptr; vptr = ptr; ptr = qSharedPointerConstCast<Data>(cptr); ptr = qSharedPointerConstCast<Data>(vptr); ptr = cptr.constCast<Data>(); ptr = vptr.constCast<Data>(); #if !defined(Q_CC_HPACC) && !defined(QT_ARCH_PARISC) // the aCC series 3 compiler we have on the PA-RISC // machine crashes compiling this code QSharedPointer<const volatile Data> cvptr(ptr); QSharedPointer<const volatile Data> cvptr2(cptr); QSharedPointer<const volatile Data> cvptr3(vptr); cvptr = ptr; cvptr2 = cptr; cvptr3 = vptr; ptr = qSharedPointerConstCast<Data>(cvptr); ptr = cvptr.constCast<Data>(); #endif } { Data *aData = new Data; QSharedPointer<Data> ptr = QSharedPointer<Data>(aData); const QSharedPointer<Data> cptr = ptr; ptr = cptr; QSharedPointer<Data> other = qSharedPointerCast<Data>(cptr); other = qSharedPointerDynamicCast<Data>(cptr); QCOMPARE(cptr.data(), aData); QCOMPARE(cptr.operator->(), aData); } }
/**************************** Function: VPrintf Vector: 159 Offset: -954 Arguments: D1.L pointer to format string D2.L pointer to data array Returns: D0.L number of bytes written ****************************/ int lib_dos_f_VPrintf(emumsg_syscall_t *msg) { cpu_t *cpu; uint8_t *fptr, *bptr, *sptr; uint8_t ch, *buf; uint32_t fvptr, dvptr; int rc, status, f_long; uint16_t data16; uint32_t data32; DEBUG(4) dprintf("dos.library: lib_dos_f_VPrintf() called\n"); cpu = msg->proc->cpu; DEBUG(5) dprintf(" Format string (D1): 0x%x, Data stream (D2): 0x%x\n",cpu->d[1],cpu->d[2]); if(cpu->d[1] == 0) { DEBUG(1) dprintf("Warning: dos.library: lib_dos_f_VPrintf() called with NULL format string, skipping\n"); return HOOK_DONE; } /* TODO: Implement some kind of check for MMU entry ending within the string */ /* Allocate a native buffer for the converted native data stream */ buf = (uint8_t *)AllocVec(LIB_DOS_F_VPRINTF_BUFFER_SIZE,MEMF_PUBLIC|MEMF_CLEAR); if(buf == NULL) { dprintf("Error: dos.library: lib_dos_f_VPrintf: AllocVec failed for buffer\n"); return HOOK_END_PROC; } bptr = buf; /* Loop through the string to build a special mapping for the data stream */ fvptr = cpu->d[1]; dvptr = cpu->d[2]; status = 0; f_long = 0; rc = READMEM_8(fvptr++, &ch); if(rc) return rc; while(ch != '\0'){ if(status == 0) { /* Idle, look for a % */ if(ch == '%') { f_long = 0; status = 1; } } else { /* Got a % */ if(ch=='-' || (ch>='0' && ch<='9') || ch=='.') { /* Format parameters */ } else if(ch=='l') { /* Long indicator */ f_long = 1; } else if(ch=='d' || ch=='u' || ch=='x' || ch=='c') { /* Signed decimal, unsigned decimal, hexadecimal or character */ if(f_long) { /* 32bit data */ rc = READMEM_32(dvptr, &data32); if(rc) return rc; dvptr += 4; *((ULONG *)bptr)=(ULONG)data32; bptr += sizeof(LONG); } else { /* 16bit data */ rc = READMEM_16(dvptr, &data16); if(rc) return rc; dvptr += 2; *((UWORD *)bptr)=(UWORD)data32; bptr += sizeof(UWORD); } status = 0; } else if(ch=='s') { /* String */ /* 32bit pointer */ rc = READMEM_32(dvptr, &data32); if(rc) return rc; dvptr += 4; /* Get native pointer to string */ sptr = vptr(data32); /* TODO: Check mappings */ *((APTR *)bptr)=(APTR)sptr; bptr += sizeof(APTR); status = 0; } else if(ch=='b') { /* BString */ /* 32bit pointer */ rc = READMEM_32(dvptr, &data32); if(rc) return rc; dvptr += 4; /* BPTR -> APTR */ data32 <<= 2; /* Get native pointer to string */ sptr = vptr(data32); /* TODO: Check mappings */ *((BPTR *)bptr)=MKBADDR((APTR)sptr); bptr += sizeof(BPTR); status = 0; } else { /* Literal % or illegal char */ status = 0; } } rc = READMEM_8(fvptr++, &ch); if(rc) return rc; } fptr = vptr(cpu->d[1]); DEBUG(5) dprintf(" Format string (native): %p, Data stream (native): %p\n",fptr,buf); /* Prepare syscall */ msg->arg[0]._strptr = (STRPTR)fptr; msg->arg[1]._aptr = (APTR)buf; /* Remember buffer */ msg->internalPtr = buf; return HOOK_SYSCALL; }
/**************************** Function: ReadArgs Vector: 133 Offset: -798 Arguments: D1.L pointer to argument string D2.L pointer to array of longs D3.L pointer to structure RDArgs Returns: D0.L pointer to structure RDArgs ****************************/ int lib_dos_f_ReadArgs(emumsg_syscall_t *msg) { cpu_t *cpu; struct RDArgs *rdargs_real; lib_dos_s_rdargs_t *rdargs; int slen, i; uint8_t *controlStr, *sptr, prevch; uint32_t longdata; uint8_t *argstring; DEBUG(4) dprintf("dos.library: lib_dos_f_ReadArgs() called\n"); cpu = msg->proc->cpu; DEBUG(5) dprintf(" Argument string (D1): 0x%x, Ptr array (D2): 0x%x, Ptr RDArgs (D3): 0x%x\n",cpu->d[1],cpu->d[2],cpu->d[3]); if(cpu->d[3] != 0) { dprintf("Error: dos.library: ReadArgs: Supplying a RDArgs pointer is not supported\n"); return HOOK_END_PROC; } /* TODO: Implement some kind of check for MMU entry ending within the string */ sptr = vptr(cpu->d[1]); if(sptr == NULL) { /* Illegal VADDR */ dprintf("Error: dos.library: ReadArgs: String pointer adress is invalid. Ptr=0x%x\n",cpu->d[1]); return HOOK_END_PROC; } DEBUG(5) dprintf(" Argument string (native): %p\n",sptr); slen = strlen((char *)sptr); if(slen==0) { /* Nothing to do.. */ cpu->d[0]=0; return HOOK_DONE; } controlStr = sptr; /* DEBUG dprintf("Control string: %s\n",controlStr); */ /* TODO: Is AllocDosObject suitable to use from the library process? */ /* Prepare our own RDArgs structure */ rdargs_real = (struct RDArgs *)AllocDosObject(DOS_RDARGS, NULL); if(rdargs_real == NULL) { dprintf("Error: dos.library: ReadArgs: Could not allocate dos object for struct RDArgs\n"); return HOOK_END_PROC; } /* Get mapped structure */ rdargs = lib_dos_s_rdargs_get_real(rdargs_real); if(rdargs == 0) { /* Error */ dprintf("Error: dos.library: ReadArgs: Failed to create RDArgs mapping\n"); FreeDosObject(DOS_RDARGS, rdargs_real); return HOOK_END_PROC; } rdargs->cnt = 1; rdargs->type[rdargs->cnt-1] = LIB_DOS_S_RDARGS_ARGTYPE_STRING; prevch = '\0'; while(*sptr != '\0'){ if(*sptr == ','){ /* New arg */ rdargs->cnt++; if(rdargs->cnt > LIB_DOS_S_RDARGS_ARGS_MAX) { /* Too many */ dprintf("Error: dos.library: ReadArgs: Too many arguments\n"); mmu_delEntry(rdargs->entry); FreeDosObject(DOS_RDARGS, rdargs_real); return HOOK_END_PROC; } rdargs->type[rdargs->cnt-1] = LIB_DOS_S_RDARGS_ARGTYPE_STRING; } if(prevch == '/'){ switch(*sptr) { case 's': case 'S': case 't': case 'T': rdargs->type[rdargs->cnt-1] = LIB_DOS_S_RDARGS_ARGTYPE_BOOLEAN; break; case 'n': case 'N': rdargs->type[rdargs->cnt-1] = LIB_DOS_S_RDARGS_ARGTYPE_INTEGER; break; case 'm': case 'M': rdargs->type[rdargs->cnt-1] = LIB_DOS_S_RDARGS_ARGTYPE_STRINGARRAY; break; default: break; } } prevch = *sptr++; } /* DEBUG for(i=0;i < rdargs->cnt;i++) { dprintf("Arg %d type %d\n",i,rdargs->type[i]); } */ /* Init defaults */ for(i=0;i < rdargs->cnt;i++) { if(READMEM_32(cpu->d[2]+4*i, &longdata)) { /* Read failed */ dprintf("Error: dos.library: ReadArgs: Failed to read initially set values\n"); mmu_delEntry(rdargs->entry); FreeDosObject(DOS_RDARGS, rdargs_real); return HOOK_END_PROC; } rdargs->data[i] = (IPTR)longdata; if(longdata != 0) { if(rdargs->type[i] == LIB_DOS_S_RDARGS_ARGTYPE_STRING || rdargs->type[i] == LIB_DOS_S_RDARGS_ARGTYPE_STRINGARRAY) { /* A string was defined. Set the IPTR to point to the struct. This way we can determine if ReadArgs() has set a new pointer value without having to set up mappings for the original strings. ReadArgs() is not reading the initial strings anyway. */ rdargs->data[i] = (IPTR)rdargs; } } } /* Init RDArgs CSource with our argument string */ argstring = vptr(msg->proc->vaddr_args); rdargs_real->RDA_Source.CS_Buffer = argstring; rdargs_real->RDA_Source.CS_Length = strlen((char *)argstring); rdargs_real->RDA_Source.CS_CurChr = 0; /* Prepare syscall */ msg->arg[0]._strptr = (STRPTR)controlStr; msg->arg[1]._aptr = (APTR)rdargs->data; msg->arg[2]._aptr = (APTR)rdargs_real; /* Remember the rdargs structure */ msg->internalPtr = rdargs; /* Do syscall */ return HOOK_SYSCALL; }
JSFunction::~JSFunction() { ASSERT(vptr() == JSGlobalData::jsFunctionVPtr); }
void* fetch_in_addr(int family, sockaddr* addr) { if (family == AF_INET) return vptr(&reinterpret_cast<sockaddr_in*>(addr)->sin_addr); return vptr(&reinterpret_cast<sockaddr_in6*>(addr)->sin6_addr); }
AJArrayArray::~AJArrayArray() { ASSERT(vptr() == AJGlobalData::jsByteArrayVPtr); }
int compare(CTXTdeclc const void * v1, const void * v2) { int comp; CPtr cptr1, cptr2; Cell val1 = (Cell) v1 ; Cell val2 = (Cell) v2 ; XSB_Deref(val2); /* val2 is not in register! */ XSB_Deref(val1); /* val1 is not in register! */ if (val1 == val2) return 0; switch(cell_tag(val1)) { case XSB_FREE: case XSB_REF1: if (isattv(val2)) return vptr(val1) - (CPtr)dec_addr(val2); else if (isnonvar(val2)) return -1; else { /* in case there exist local stack variables in the */ /* comparison, globalize them to guarantee that their */ /* order is retained as long as nobody "touches" them */ /* in the future -- without copying garbage collection */ if ((top_of_localstk <= vptr(val1)) && (vptr(val1) <= (CPtr)glstack.high-1)) { bld_free(hreg); bind_ref(vptr(val1), hreg); hreg++; val1 = follow(val1); /* deref again */ } if ((top_of_localstk <= vptr(val2)) && (vptr(val2) <= (CPtr)glstack.high-1)) { bld_free(hreg); bind_ref(vptr(val2), hreg); hreg++; val2 = follow(val2); /* deref again */ } return vptr(val1) - vptr(val2); } case XSB_FLOAT: if (isref(val2) || isattv(val2)) return 1; else if (isofloat(val2)) return sign(float_val(val1) - ofloat_val(val2)); else return -1; case XSB_INT: if (isref(val2) || isofloat(val2) || isattv(val2)) return 1; else if (isinteger(val2)) return int_val(val1) - int_val(val2); else if (isboxedinteger(val2)) return int_val(val1) - boxedint_val(val2); else return -1; case XSB_STRING: if (isref(val2) || isofloat(val2) || isinteger(val2) || isattv(val2)) return 1; else if (isstring(val2)) { return strcmp(string_val(val1), string_val(val2)); } else return -1; case XSB_STRUCT: // below, first 2 if-checks test to see if this struct is actually a number representation, // (boxed float or boxed int) and if so, does what the number case would do, only with boxed_val // macros. if (isboxedinteger(val1)) { if (isref(val2) || isofloat(val2) || isattv(val2)) return 1; else if (isinteger(val2)) return boxedint_val(val1) - int_val(val2); else if (isboxedinteger(val2)) return boxedint_val(val1) - boxedint_val(val2); else return -1; } else if (isboxedfloat(val1)) { if (isref(val2) || isattv(val2)) return 1; else if (isofloat(val2)) return sign(boxedfloat_val(val1) - ofloat_val(val2)); else return -1; } else if (cell_tag(val2) != XSB_STRUCT && cell_tag(val2) != XSB_LIST) return 1; else { int arity1, arity2; Psc ptr1 = get_str_psc(val1); Psc ptr2 = get_str_psc(val2); arity1 = get_arity(ptr1); if (islist(val2)) arity2 = 2; else arity2 = get_arity(ptr2); if (arity1 != arity2) return arity1-arity2; if (islist(val2)) comp = strcmp(get_name(ptr1), "."); else comp = strcmp(get_name(ptr1), get_name(ptr2)); if (comp || (arity1 == 0)) return comp; cptr1 = clref_val(val1); cptr2 = clref_val(val2); for (arity2 = 1; arity2 <= arity1; arity2++) { if (islist(val2)) comp = compare(CTXTc (void*)cell(cptr1+arity2), (void*)cell(cptr2+arity2-1)); else comp = compare(CTXTc (void*)cell(cptr1+arity2), (void*)cell(cptr2+arity2)); if (comp) break; } return comp; } break; case XSB_LIST: if (cell_tag(val2) != XSB_STRUCT && cell_tag(val2) != XSB_LIST) return 1; else if (isconstr(val2)) return -(compare(CTXTc (void*)val2, (void*)val1)); else { /* Here we are comparing two list structures. */ cptr1 = clref_val(val1); cptr2 = clref_val(val2); comp = compare(CTXTc (void*)cell(cptr1), (void*)cell(cptr2)); if (comp) return comp; return compare(CTXTc (void*)cell(cptr1+1), (void*)cell(cptr2+1)); } break; case XSB_ATTV: if (isattv(val2)) return (CPtr)dec_addr(val1) - (CPtr)dec_addr(val2); else if (isref(val2)) return (CPtr)dec_addr(val1) - vptr(val2); else return -1; default: xsb_abort("Compare (unknown tag %ld); returning 0", cell_tag(val1)); return 0; } }
JSString::~JSString() { ASSERT(vptr() == JSGlobalData::jsStringVPtr); }
/**************************** Function: FormatDate Vector: 10 Offset: -60 Arguments: A0.L pointer to struct Locale A1.L pointer to format string A2.L pointer to struct DateStamp A3.L pointer to struct Hook Returns: - Comment: Issues callbacks via the hook structure. Parameters: A0.L pointer to struct Hook A1.B the emitted character A2.L pointer to struct Locale The function is called with the NULL char ('\0') at the end ****************************/ int lib_locale_f_FormatDate(emumsg_syscall_t *msg) { cpu_t *cpu; lib_locale_s_locale_t *locale; struct Locale *locale_real; lib_dos_s_datestamp_t *datestamp; lib_utility_s_hook_t *hook; STRPTR fstr; DEBUG(4) dprintf("locale.library: lib_locale_f_FormatDate() called\n"); cpu = msg->proc->cpu; DEBUG(5) dprintf(" Locale ptr (A0): 0x%x, Format string ptr (A1): 0x%x, DateStamp ptr (A2): 0x%x, Hook ptr (A3): 0x%x\n",cpu->a[0],cpu->a[1],cpu->a[2],cpu->a[3]); if(cpu->a[2] == 0) { DEBUG(2) dprintf("Warning: locale.library: lib_locale_f_FormatDate: Pointer to struct DateStamp is NULL.\n"); return HOOK_DONE; } if(cpu->a[3] == 0) { DEBUG(2) dprintf("Warning: locale.library: lib_locale_f_FormatDate: Pointer to struct Hook is NULL.\n"); return HOOK_DONE; } /* Can be null */ locale_real = NULL; locale = lib_locale_s_locale_get_vaddr(cpu->a[0]); if(locale != NULL) { locale_real = locale->real; } /* Can be null */ fstr = (STRPTR)vptr(cpu->a[1]); /* TODO: Implement some kind of check for MMU entry ending within the string */ datestamp = lib_dos_s_datestamp_get_vaddr(cpu->a[2]); if(datestamp == NULL) { DEBUG(1) dprintf("Error: locale.library: lib_locale_f_FormatDate: DateStamp pointer is invalid\n"); return HOOK_END_PROC; } hook = lib_utility_s_hook_get_vaddr(cpu->a[3]); if(hook == NULL) { DEBUG(1) dprintf("Error: locale.library: lib_locale_f_FormatDate: Hook pointer is invalid\n"); return HOOK_END_PROC; } DEBUG(5) dprintf(" Locale ptr (native): %p, Format string ptr (native): %p, DateStamp ptr (native): %p, Hook ptr (native): %p\n",locale_real,fstr,datestamp->real,hook->real); /* Prepare the CPU structure for callback */ /* Save PC */ cpu->a[7] -= 4; if(WRITEMEM_32(cpu->pc, cpu->a[7])){ DEBUG(1) dprintf("Error: locale.library: lib_locale_f_FormatDate: Could not write to stack\n"); return HOOK_END_PROC; } /* Set return address for RTS in the end of the callback so it executes the special TRAP */ cpu->a[7] -= 4; if(WRITEMEM_32(helper_vaddr, cpu->a[7])){ DEBUG(1) dprintf("Error: locale.library: lib_locale_f_FormatDate: Could not write to stack\n"); return HOOK_END_PROC; } /* Put the msg into the hook so it can be reached from within the callback */ hook->msg = msg; /* Prepare syscall */ msg->arg[0]._aptr = (APTR)locale_real; msg->arg[1]._strptr = fstr; msg->arg[2]._aptr = (APTR)datestamp->real; msg->arg[3]._aptr = (APTR)hook->real; return HOOK_SYSCALL; }
JSByteArray::~JSByteArray() { ASSERT(vptr() == JSGlobalData::jsByteArrayVPtr); }
// tests whether the plugin can be loaded bool KDecorationPlugins::canLoad(QString nameStr, KLibrary **loadedLib) { if (nameStr.isEmpty()) return false; // we can't load that // Check if this library is not already loaded. if (pluginStr == nameStr) { if (loadedLib) { *loadedLib = library; } return true; } KConfigGroup group(config, QString("Style")); if (group.readEntry<bool>("NoPlugin", false)) { error(i18n("Loading of window decoration plugin library disabled in configuration.")); return false; } KLibrary libToFind(nameStr); QString path = libToFind.fileName(); kDebug(1212) << "kwin : path " << path << " for " << nameStr; if (path.isEmpty()) { return false; } // Try loading the requested plugin KLibrary *lib = new KLibrary(path); if (!lib) return false; // TODO this would be a nice shortcut, but for "some" reason QtCurve with wrong ABI slips through // TODO figure where it's loaded w/o being unloaded and check whether that can be fixed. #if 0 if (lib->isLoaded()) { if (loadedLib) { *loadedLib = lib; } return true; } #endif // so we check whether this lib was loaded before and don't unload it in case bool wasLoaded = lib->isLoaded(); KDecorationFactory*(*cptr)() = NULL; int (*vptr)() = NULL; int deco_version = 0; KLibrary::void_function_ptr version_func = lib->resolveFunction("decoration_version"); if (version_func) { vptr = (int(*)())version_func; deco_version = vptr(); } else { // block some decos known to link the unstable API but (for now) let through other legacy stuff const bool isLegacyStableABI = !(nameStr.contains("qtcurve", Qt::CaseInsensitive) || nameStr.contains("crystal", Qt::CaseInsensitive) || nameStr.contains("oxygen", Qt::CaseInsensitive)); if (isLegacyStableABI) { // it's an old build of a legacy decoration that very likely uses the stable API // so we just set the API version to the current one // TODO: remove for 4.9.x or 4.10 - this is just to cover recompiles deco_version = KWIN_DECORATION_API_VERSION; } kWarning(1212) << QString("****** The library %1 has no API version ******").arg(path); kWarning(1212) << "****** Please use the KWIN_DECORATION macro in extern \"C\" to get this decoration loaded in future versions of kwin"; } if (deco_version != KWIN_DECORATION_API_VERSION) { if (version_func) kWarning(1212) << i18n("The library %1 has wrong API version %2", path, deco_version); lib->unload(); delete lib; return false; } KLibrary::void_function_ptr create_func = lib->resolveFunction("create_factory"); if (create_func) cptr = (KDecorationFactory * (*)())create_func; if (!cptr) { kDebug(1212) << i18n("The library %1 is not a KWin plugin.", path); lib->unload(); delete lib; return false; } if (loadedLib) { *loadedLib = lib; } else { if (!wasLoaded) lib->unload(); delete lib; } return true; }