/* this routine is called when a new "object" is requested whose class Pd doesn't know. Pd tries to load it as an extern, then as an abstraction. */ void new_anything(void *dummy, t_symbol *s, int argc, t_atom *argv) { t_pd *current; int fd; char dirbuf[MAXPDSTRING], *nameptr; if (tryingalready) return; newest = 0; class_loadsym = s; if (sys_load_lib(canvas_getcurrent(), s->s_name)) { tryingalready = 1; typedmess(dummy, s, argc, argv); tryingalready = 0; return; } class_loadsym = 0; current = s__X.s_thing; if ((fd = canvas_open(canvas_getcurrent(), s->s_name, ".pd", dirbuf, &nameptr, MAXPDSTRING, 0)) >= 0 || (fd = canvas_open(canvas_getcurrent(), s->s_name, ".pat", dirbuf, &nameptr, MAXPDSTRING, 0)) >= 0) { close (fd); if (!pd_setloadingabstraction(s)) { canvas_setargs(argc, argv); binbuf_evalfile(gensym(nameptr), gensym(dirbuf)); if (s__X.s_thing != current) canvas_popabstraction((t_canvas *)(s__X.s_thing)); canvas_setargs(0, 0); } else error("%s: can't load abstraction within itself\n", s->s_name); } else newest = 0; }
/** * the loader * * @param canvas the context of the object to be created * @param classname the name of the object (external, library) to be created * @return 1 on success, 0 on failure */ static int autoabstraction_loader(t_canvas *canvas, char *classname) { /* check whether there is an abstraction with the given <classname> within the scope of <canvas> */ int fd=0; char dirbuf[MAXPDSTRING], *nameptr; if((fd=canvas_open(canvas, classname, ".pd", dirbuf, &nameptr, MAXPDSTRING, 0)) >= 0 || (fd=canvas_open(canvas, classname, ".pat", dirbuf, &nameptr, MAXPDSTRING, 0)) >= 0) { /* oops, there's already an abstraction of the given <classname> */ close(fd); return(0); } autoabstraction_createpatch(canvas, classname); /* we always fail, because we want Pd to do the real opening of abstractions */ return 0; }
/* this routine is called when a new "object" is requested whose class Pd doesn't know. Pd tries to load it as an extern, then as an abstraction. */ void new_anything(void *dummy, t_symbol *s, int argc, t_atom *argv) { t_pd *current; int fd; char dirbuf[MAXPDSTRING], classslashclass[MAXPDSTRING], *nameptr; if (tryingalready>MAXOBJDEPTH){ error("maximum object loading depth %d reached", MAXOBJDEPTH); return; } newest = 0; class_loadsym = s; if (sys_load_lib(canvas_getcurrent(), s->s_name)) { tryingalready++; typedmess(dummy, s, argc, argv); tryingalready--; return; } class_loadsym = 0; current = s__X.s_thing; /* for class/class.pd support, to match class/class.pd_linux */ snprintf(classslashclass, MAXPDSTRING, "%s/%s", s->s_name, s->s_name); if ((fd = canvas_open(canvas_getcurrent(), s->s_name, ".pd", dirbuf, &nameptr, MAXPDSTRING, 0)) >= 0 || (fd = canvas_open(canvas_getcurrent(), s->s_name, ".pat", dirbuf, &nameptr, MAXPDSTRING, 0)) >= 0 || (fd = canvas_open(canvas_getcurrent(), classslashclass, ".pd", dirbuf, &nameptr, MAXPDSTRING, 0)) >= 0) { close (fd); if (!pd_setloadingabstraction(s)) { canvas_setargs(argc, argv); binbuf_evalfile(gensym(nameptr), gensym(dirbuf)); canvas_initbang((t_canvas *)(s__X.s_thing));/* JMZ*/ if (s__X.s_thing != current) canvas_popabstraction((t_canvas *)(s__X.s_thing)); canvas_setargs(0, 0); } else error("%s: can't load abstraction within itself\n", s->s_name); } else newest = 0; }
static t_pd *do_create_abstraction(t_symbol*s, int argc, t_atom *argv) { /* * TODO: check if the there is a binbuf cached for <canvas::symbol> and use that instead. We'll have to invalidate the cache once we are done (either with a clock_delay(0) or something else) */ if (!pd_setloadingabstraction(s)) { const char *objectname = s->s_name; char dirbuf[MAXPDSTRING], classslashclass[MAXPDSTRING], *nameptr; t_glist *glist = (t_glist *)canvas_getcurrent(); t_canvas *canvas = (t_canvas*)glist_getcanvas(glist); int fd = -1; t_pd *was = s__X.s_thing; snprintf(classslashclass, MAXPDSTRING, "%s/%s", objectname, objectname); if ((fd = canvas_open(canvas, objectname, ".pd", dirbuf, &nameptr, MAXPDSTRING, 0)) >= 0 || (fd = canvas_open(canvas, objectname, ".pat", dirbuf, &nameptr, MAXPDSTRING, 0)) >= 0 || (fd = canvas_open(canvas, classslashclass, ".pd", dirbuf, &nameptr, MAXPDSTRING, 0)) >= 0) { close(fd); canvas_setargs(argc, argv); binbuf_evalfile(gensym(nameptr), gensym(dirbuf)); if (s__X.s_thing && was != s__X.s_thing) canvas_popabstraction((t_canvas *)(s__X.s_thing)); else s__X.s_thing = was; canvas_setargs(0, 0); return (pd_this->pd_newest); } /* otherwise we couldn't do it; just return 0 */ } else error("%s: can't load abstraction within itself\n", s->s_name); pd_this->pd_newest = 0; return (0); }
static void helplink_doclick(t_helplink *x) { char* objectname = x->x_ulink->s_name; char dirbuf[MAXPDSTRING], *nameptr; int fd = canvas_open(x->x_glist, objectname, "-help.pd", dirbuf, &nameptr, MAXPDSTRING, 0); if (fd < 0) { /* if canvas_open() failed try open_via_helppath() */ open_via_helppath(objectname, canvas_getdir(x->x_glist)->s_name); } else { /* if canvas_open() gave us a filehandle, then we have a helppatch to * open in dirbuf and nameptr, but we don't need the filehandle */ close(fd); glob_evalfile(NULL, gensym(nameptr), gensym(dirbuf)); } }
static int libdir_loader_legacy(t_canvas *canvas, char *classname) { int fd = -1; char fullclassname[FILENAME_MAX], dirbuf[FILENAME_MAX]; char *nameptr; /* look for meta file (classname)/(classname)-meta.pd */ libdir_get_fullname(fullclassname, FILENAME_MAX, classname); /* if this is being called from a canvas, then add the library path to the * canvas-local path */ if(canvas) /* setting the canvas to NULL causes it to ignore any canvas-local path */ fd = canvas_open(NULL, fullclassname, ".pd", dirbuf, &nameptr, FILENAME_MAX, 0); else fd = open_via_path(".", fullclassname, ".pd", dirbuf, &nameptr, FILENAME_MAX, 0); if(fd < 0) { return (0); } sys_close(fd); #if 0 if(!canvas) { char helppathname[FILENAME_MAX]; strncpy(helppathname, sys_libdir->s_name, FILENAME_MAX-30); helppathname[FILENAME_MAX-30] = 0; strcat(helppathname, "/doc/5.reference/"); strcat(helppathname, classname); sys_helppath = namelist_append(sys_helppath, helppathname, 0); } #endif if(libdir_add_to_path(dirbuf, canvas)) logpost(NULL, 3, "libdir_loader: added '%s' to the %s objectclass path", classname, canvas?"canvas-local":"global"); /* post("libdir_loader loaded fullclassname: '%s'\n", fullclassname); */ logpost(NULL, 14, "Loaded libdir '%s' from '%s'", classname, dirbuf); return (1); }
static std::string getFullfilename(const t_canvas*canvas, const char*filename, const char*ext) { std::string fullname_; char buf[MAXPDSTRING]; char*bufptr; int fd=0; if ((fd=canvas_open(const_cast<t_canvas*>(canvas), filename, ext, buf, &bufptr, MAXPDSTRING, 1))>=0){ ::close(fd); fullname_=buf; fullname_+="/"; fullname_+=bufptr; } else { if(canvas) { canvas_makefilename(const_cast<t_canvas*>(canvas), const_cast<char*>(filename), buf, MAXPDSTRING); fullname_=buf; } else { return std::string(""); } } return fullname_; }
/* tries to expand the given filename to it's full glory) */ t_symbol*get_filename(t_canvas*canvas, t_symbol*s) { int fd=0; char buf[MAXPDSTRING]; char result[MAXPDSTRING]; char*bufptr; if(!s || !s->s_name || !*s->s_name) { return NULL; } if ((fd=canvas_open(canvas, s->s_name, "", buf, &bufptr, MAXPDSTRING, 1))>=0){ sys_close(fd); snprintf(result, MAXPDSTRING-1, "%s/%s", buf, bufptr); result[MAXPDSTRING-1]=0; return gensym(result); } else if(canvas) { canvas_makefilename(canvas, s->s_name, result, MAXPDSTRING); return gensym(result); } return s; }
bool open(std::string name, const t_canvas*canvas) { bool loud=false; const char*hookname="plugMain"; if(name.empty()) return false; if(m_plugin) close(); FF_Main_FuncPtr plugmain = NULL; char buf[MAXPDSTRING]; char buf2[MAXPDSTRING]; char *bufptr=NULL; const char *extension= #ifdef _WIN32 ".dll"; #elif defined __APPLE__ ""; #else ".so"; #endif #ifdef __APPLE__ char buf3[MAXPDSTRING]; #ifdef DL_OPEN snprintf(buf3, MAXPDSTRING, "%s.frf/Contents/MacOS/%s", name.c_str(), name.c_str()); #else // this can never work... snprintf(buf3, MAXPDSTRING, "%s.frf/%s", name.c_str(), name.c_str()); #endif buf3[MAXPDSTRING-1]=0; name=buf3; #endif int fd=-1; if ((fd=canvas_open(const_cast<t_canvas*>(canvas), name.c_str(), extension, buf2, &bufptr, MAXPDSTRING, 1))>=0){ ::close(fd); #if defined __APPLE__ && 0 snprintf(buf, MAXPDSTRING, "%s", buf2); #else snprintf(buf, MAXPDSTRING, "%s/%s", buf2, bufptr); #endif buf[MAXPDSTRING-1]=0; } else { if(canvas) { canvas_makefilename(const_cast<t_canvas*>(canvas), const_cast<char*>(name.c_str()), buf, MAXPDSTRING); } else { if(loud)::error("pix_freeframe[%s]: unfindeable", name.c_str()); return false; } } name=buf; std::string libname = name; if(loud)::post("trying to load %s", buf); #ifdef DL_OPEN if(loud)::post("dlopen %s", libname.c_str()); m_dlhandle=dlopen(libname.c_str(), RTLD_NOW); if(!m_dlhandle){ if(loud)::error("pix_freeframe[%s]: %s", libname.c_str(), dlerror()); return NULL; } dlerror(); plugmain = reinterpret_cast<FF_Main_FuncPtr>(dlsym(m_dlhandle, hookname)); #elif defined __APPLE__ CFURLRef bundleURL = NULL; CFBundleRef theBundle = NULL; CFStringRef plugin = CFStringCreateWithCString(NULL, libname.c_str(), kCFStringEncodingMacRoman); bundleURL = CFURLCreateWithFileSystemPath( kCFAllocatorSystemDefault, plugin, kCFURLPOSIXPathStyle, true ); theBundle = CFBundleCreate( kCFAllocatorSystemDefault, bundleURL ); // Get a pointer to the function. if (theBundle){ plugmain = reinterpret_cast<FF_Main_FuncPtr>(CFBundleGetFunctionPointerForName( theBundle, CFSTR("plugMain") ) ); }else{ if(loud)::post("%s: couldn't load", libname.c_str()); return 0; } if(bundleURL != NULL) CFRelease( bundleURL ); if(theBundle != NULL) CFRelease( theBundle ); if(plugin != NULL) CFRelease( plugin ); #elif defined _WIN32 char buffer[MAXPDSTRING]; sys_bashfilename(libname.c_str(), buffer); libname=buffer; m_w32handle = LoadLibrary(libname.c_str()); if (!m_w32handle) { if(loud)::post("%s: couldn't load", libname.c_str()); return false; } plugmain = reinterpret_cast<FF_Main_FuncPtr>(GetProcAddress(m_w32handle, hookname)); #else # error no way to load dynamic linked libraries on this OS #endif m_plugin=plugmain; return (NULL!=m_plugin); }
static void selected(const wimp_selection *selection, void *opaque) { NOT_USED(opaque); switch (selection->items[0]) { #ifdef EYE_CANVAS case ICONBAR_NEW: switch (selection->items[1]) { case NEW_CANVAS: { error err; canvas_t *canvas; err = canvas_create(&canvas); if (err) return; canvas_open(canvas); } break; } break; #endif /* Close all */ case ICONBAR_CLOSE: switch (selection->items[1]) { case CLOSE_VIEWERS: if (can_quit()) viewer_close_all(); break; #ifdef EYE_THUMBVIEW case CLOSE_THUMBVIEWS: thumbview_close_all(); break; #endif #ifdef EYE_CANVAS case CLOSE_CANVASES: canvas_close_all(); break; #endif } break; case ICONBAR_EMPTYCACHE: imagecache_empty(); break; #ifdef EYE_TAGS case ICONBAR_SEARCHTAGS: tags_search_open(); break; #endif case ICONBAR_CHOICES: /* Choices... */ choices_open(&privateeye_choices); break; case ICONBAR_QUIT: /* Quit */ if (can_quit()) GLOBALS.flags |= Flag_Quit; break; } }
static int sys_do_load_lib(t_canvas *canvas, char *objectname) { char symname[MAXPDSTRING], filename[MAXPDSTRING], dirbuf[MAXPDSTRING], *classname, *nameptr, altsymname[MAXPDSTRING]; void *dlobj; t_xxx makeout = NULL; int i, hexmunge = 0, fd; #ifdef _WIN32 HINSTANCE ntdll; #endif if (classname = strrchr(objectname, '/')) classname++; else classname = objectname; if (sys_onloadlist(objectname)) { post("%s: already loaded", objectname); return (1); } for (i = 0, nameptr = classname; i < MAXPDSTRING-7 && *nameptr; nameptr++) { char c = *nameptr; if ((c>='0' && c<='9') || (c>='A' && c<='Z')|| (c>='a' && c<='z' )|| c == '_') { symname[i] = c; i++; } /* trailing tilde becomes "_tilde" */ else if (c == '~' && nameptr[1] == 0) { strcpy(symname+i, "_tilde"); i += strlen(symname+i); } else /* anything you can't put in a C symbol is sprintf'ed in hex */ { sprintf(symname+i, "0x%02x", c); i += strlen(symname+i); hexmunge = 1; } } symname[i] = 0; if (hexmunge) { memmove(symname+6, symname, strlen(symname)+1); strncpy(symname, "setup_", 6); } else strcat(symname, "_setup"); #if 0 fprintf(stderr, "lib: %s\n", classname); #endif /* try looking in the path for (objectname).(sys_dllextent) ... */ if ((fd = canvas_open(canvas, objectname, sys_dllextent, dirbuf, &nameptr, MAXPDSTRING, 1)) >= 0) goto gotone; /* same, with the more generic sys_dllextent2 */ if ((fd = canvas_open(canvas, objectname, sys_dllextent2, dirbuf, &nameptr, MAXPDSTRING, 1)) >= 0) goto gotone; /* next try (objectname)/(classname).(sys_dllextent) ... */ strncpy(filename, objectname, MAXPDSTRING); filename[MAXPDSTRING-2] = 0; strcat(filename, "/"); strncat(filename, classname, MAXPDSTRING-strlen(filename)); filename[MAXPDSTRING-1] = 0; if ((fd = canvas_open(canvas, filename, sys_dllextent, dirbuf, &nameptr, MAXPDSTRING, 1)) >= 0) goto gotone; if ((fd = canvas_open(canvas, filename, sys_dllextent2, dirbuf, &nameptr, MAXPDSTRING, 1)) >= 0) goto gotone; return (0); gotone: close(fd); class_set_extern_dir(gensym(dirbuf)); /* rebuild the absolute pathname */ strncpy(filename, dirbuf, MAXPDSTRING); filename[MAXPDSTRING-2] = 0; strcat(filename, "/"); strncat(filename, nameptr, MAXPDSTRING-strlen(filename)); filename[MAXPDSTRING-1] = 0; #ifdef HAVE_LIBDL dlobj = dlopen(filename, RTLD_NOW | RTLD_GLOBAL); if (!dlobj) { post("%s: %s", filename, dlerror()); class_set_extern_dir(&s_); return (0); } makeout = (t_xxx)dlsym(dlobj, symname); /* fprintf(stderr, "symbol %s\n", symname); */ #endif #ifdef _WIN32 sys_bashfilename(filename, filename); ntdll = LoadLibrary(filename); if (!ntdll) { post("%s: couldn't load", filename); class_set_extern_dir(&s_); return (0); } makeout = (t_xxx)GetProcAddress(ntdll, symname); #endif if (!makeout) { post("load_object: Symbol \"%s\" not found", symname); class_set_extern_dir(&s_); return 0; } (*makeout)(); class_set_extern_dir(&s_); sys_putonloadlist(objectname); return (1); }
static int sys_do_load_lib(t_canvas *canvas, char *objectname) { char symname[MAXPDSTRING], filename[MAXPDSTRING], dirbuf[MAXPDSTRING], *classname, *nameptr, altsymname[MAXPDSTRING]; void *dlobj; t_xxx makeout = NULL; int i, hexmunge = 0, fd; #ifdef _WIN32 HINSTANCE ntdll; #endif if (classname = strrchr(objectname, '/')) classname++; else classname = objectname; if (sys_onloadlist(objectname)) { post("%s: already loaded", objectname); return (1); } for (i = 0, nameptr = classname; i < MAXPDSTRING-7 && *nameptr; nameptr++) { char c = *nameptr; if ((c>='0' && c<='9') || (c>='A' && c<='Z')|| (c>='a' && c<='z' )|| c == '_') { symname[i] = c; i++; } /* trailing tilde becomes "_tilde" */ else if (c == '~' && nameptr[1] == 0) { strcpy(symname+i, "_tilde"); i += strlen(symname+i); } else /* anything you can't put in a C symbol is sprintf'ed in hex */ { sprintf(symname+i, "0x%02x", c); i += strlen(symname+i); hexmunge = 1; } } symname[i] = 0; if (hexmunge) { memmove(symname+6, symname, strlen(symname)+1); strncpy(symname, "setup_", 6); } else strcat(symname, "_setup"); #if 0 fprintf(stderr, "lib: %s\n", classname); #endif /* try looking in the path for (objectname).(sys_dllextent) ... */ if ((fd = canvas_open(canvas, objectname, sys_dllextent, dirbuf, &nameptr, MAXPDSTRING, 1)) >= 0) goto gotone; /* same, with the more generic sys_dllextent2 */ if ((fd = canvas_open(canvas, objectname, sys_dllextent2, dirbuf, &nameptr, MAXPDSTRING, 1)) >= 0) goto gotone; /* next try (objectname)/(classname).(sys_dllextent) ... */ strncpy(filename, objectname, MAXPDSTRING); filename[MAXPDSTRING-2] = 0; strcat(filename, "/"); strncat(filename, classname, MAXPDSTRING-strlen(filename)); filename[MAXPDSTRING-1] = 0; if ((fd = canvas_open(canvas, filename, sys_dllextent, dirbuf, &nameptr, MAXPDSTRING, 1)) >= 0) goto gotone; if ((fd = canvas_open(canvas, filename, sys_dllextent2, dirbuf, &nameptr, MAXPDSTRING, 1)) >= 0) goto gotone; return (0); gotone: close(fd); class_set_extern_dir(gensym(dirbuf)); /* rebuild the absolute pathname */ strncpy(filename, dirbuf, MAXPDSTRING); filename[MAXPDSTRING-2] = 0; strcat(filename, "/"); strncat(filename, nameptr, MAXPDSTRING-strlen(filename)); filename[MAXPDSTRING-1] = 0; #ifdef _WIN32 { char dirname[MAXPDSTRING], *s, *basename; sys_bashfilename(filename, filename); /* set the dirname as DllDirectory, meaning in the path for loading other DLLs so that dependent libraries can be included in the same folder as the external. SetDllDirectory() needs a minimum supported version of Windows XP SP1 for SetDllDirectory, so WINVER must be 0x0502 */ strncpy(dirname, filename, MAXPDSTRING); s = strrchr(dirname, '\\'); basename = s; if (s && *s) *s = '\0'; if (!SetDllDirectory(dirname)) error("Could not set '%s' as DllDirectory(), '%s' might not load.", dirname, basename); /* now load the DLL for the external */ ntdll = LoadLibrary(filename); if (!ntdll) { post("%s: couldn't load", filename); class_set_extern_dir(&s_); return (0); } makeout = (t_xxx)GetProcAddress(ntdll, symname); if (!makeout) makeout = (t_xxx)GetProcAddress(ntdll, "setup"); SetDllDirectory(NULL); /* reset DLL dir to nothing */ } #elif defined HAVE_LIBDL dlobj = dlopen(filename, RTLD_NOW | RTLD_GLOBAL); if (!dlobj) { post("%s: %s", filename, dlerror()); class_set_extern_dir(&s_); return (0); } makeout = (t_xxx)dlsym(dlobj, symname); if(!makeout) makeout = (t_xxx)dlsym(dlobj, "setup"); #else #warning "No dynamic loading mechanism specified, libdl or WIN32 required for loading externals!" #endif if (!makeout) { post("load_object: Symbol \"%s\" not found", symname); class_set_extern_dir(&s_); return 0; } (*makeout)(); class_set_extern_dir(&s_); sys_putonloadlist(objectname); return (1); }