Max 5 API Reference
00001 /* 00002 jit.object.c 00003 00004 Copyright 2001-2005 - Cycling '74 00005 Joshua Kit Clayton jkc@cycling74.com 00006 00007 */ 00008 #include "jit.common.h" 00009 #include "jit.class.h" 00010 #include "jit.xml.h" 00011 #include "ext_user.h" 00012 #include "ext_wind.h" 00013 #include "ext_path.h" 00014 #include "ext_patchline.h" 00015 #include "ext_obex.h" 00016 #include "ext_systime.h" 00017 #if !TARGET_RT_MAC_MACHO 00018 #include "Folders.h" 00019 #endif 00020 #ifdef WIN_VERSION 00021 #include "resource.h" 00022 extern HINSTANCE _jitlib_hinst; 00023 #endif 00024 00025 #define F_DRAWN 16 // t_box flags no longer defined in ext_maxtypes.h, but apparently still used in this file??? [tap] 00026 00027 /** 00028 * @defgroup classmod Class Module 00029 @ingroup jitter 00030 */ 00031 00032 /** 00033 * @defgroup objectmod Object Module 00034 @ingroup jitter 00035 */ 00036 00037 /** 00038 * @defgroup utilitymod Miscellaneous Utility Module 00039 @ingroup jitter 00040 */ 00041 00042 #if TARGET_API_MAC_CARBON && !TARGET_RT_MAC_MACHO 00043 #define CLASS_JITTER ((_cfm_in_ub)?ps_jitterCFM:ps_jitter) 00044 #else 00045 #define CLASS_JITTER ps_jitter 00046 #endif 00047 #define REGOB_NAMESPACE_JITTER ps_jitter 00048 00049 static long _jit_object_init=0; 00050 static long _jit_pink_roses=0; 00051 static t_hashtab *_jcs_hash=NULL; 00052 long _cfm_in_ub=0; 00053 00054 static t_jit_class *_jit_class_class; 00055 static t_jit_class *_jit_robject_class; 00056 extern t_jit_class *_jit_linklist_class; 00057 00058 #if (TARGET_RT_MAC_MACHO) 00059 char *_jit_version_str = "1.7.0"; 00060 #else 00061 #ifdef WIN_VERSION 00062 char *_jit_version_str = "1.7.0"; 00063 #else 00064 char *_jit_version_str = "1.5.3 rc4"; 00065 #endif 00066 #endif 00067 long _jit_nosplash=0; 00068 long _jit_javaload=0; 00069 00070 #ifdef WIN_VERSION 00071 static long _win_qt_init = 0; 00072 #endif 00073 00074 t_symbol *ps_jitter=NULL; 00075 t_symbol *ps_jitterCFM=NULL; 00076 00077 t_jit_err jit_object_init(void); 00078 t_jit_err jit_object_shutdown(void); 00079 method jit_class_attr_method(t_jit_class *x, t_symbol *methodname, void **attr); 00080 void jit_symbols_init(void); 00081 t_jit_err jit_err_from_max_err(t_max_err err); 00082 00083 void crawly(uchar *a, char *b); 00084 00085 #if TARGET_API_MAC_CARBON 00086 void jit_cpost_console_init(void); 00087 #endif 00088 00089 //registered object list 00090 typedef struct _jit_robject 00091 { 00092 t_jit_object ob; 00093 t_symbol *name; 00094 void *rob; 00095 long refcount; 00096 void *attachlist; 00097 } t_jit_robject; 00098 00099 t_jit_err jit_robject_init(void); 00100 void *jit_robject_new(void *x, t_symbol *s); 00101 void jit_robject_free(t_jit_robject *x); 00102 long jit_robject_symcompare(t_jit_robject *x, t_symbol *name); 00103 long jit_robject_obcompare(t_jit_robject *x, t_jit_object *o); 00104 t_messlist _jit_mess_nonmethod,_jit_mess_freemethod; 00105 00106 long _initlate=1; 00107 00108 #if TARGET_RT_MAC_MACHO 00109 char _jit_initialized = false; 00110 #endif 00111 00112 long jit_cp_isauth(void); 00113 void sched_setpollthrottle(long c, long *savethrottle); 00114 void patchline_addmess(t_symbol *s, method m); 00115 00116 void init_late(void); 00117 void terminate(void); 00118 00119 //initialization routines for internal classes 00120 t_jit_err jit_attr_init(void); 00121 t_jit_err jit_robject_init(void); 00122 t_jit_err jit_max_init(void); 00123 t_jit_err jit_matrix_init(void); 00124 t_jit_err jit_mop_init(void); 00125 t_jit_err jit_kernel_init(void); 00126 t_jit_err jit_qt_movie_init(void); 00127 t_jit_err jit_qt_record_init(void); 00128 t_jit_err jit_qt_component_init(void); 00129 t_jit_err jit_la_mult_init(void); 00130 t_jit_err jit_la_uppertri_init(void); 00131 t_jit_err jit_la_trace_init(void); 00132 t_jit_err jit_la_diagproduct_init(void); 00133 t_jit_err jit_la_determinant_init(void); 00134 t_jit_err jit_la_inverse_init(void); 00135 t_jit_err jit_gl_init(void); 00136 t_jit_err jit_op_init(void); 00137 t_jit_err jit_matrix_wrapper_init(void); 00138 t_jit_err jit_java_init(void); 00139 t_jit_err jit_functor_init(void); 00140 t_jit_err jit_listener_init(void); 00141 t_jit_err jit_charset_init(void); 00142 t_jit_err jit_xml_init(void); 00143 t_jit_err jit_tree_init(void); 00144 t_jit_err jit_expr_init(void); 00145 t_jit_err jit_uyvy_init(void); 00146 00147 #if TARGET_RT_MAC_MACHO 00148 short open_framework_resources(CFBundleRef *bun); 00149 void close_framework_resources(CFBundleRef bun, short ref); 00150 #endif 00151 00152 00153 //Move this init/maxruntime/splashscreen stuff ot a separate file 00154 long maxruntime(void) 00155 { 00156 t_patcher *p; 00157 t_symbol *nsym,*psym; 00158 method m; 00159 void *pcache,*bcache; 00160 long rv=0; 00161 t_atom av[4]; 00162 00163 jit_atom_setlong(av,0); 00164 jit_atom_setlong(av+1,0); 00165 jit_atom_setlong(av+2,10); 00166 jit_atom_setlong(av+3,10); 00167 00168 //determine if in runtime by instantiating a new vpatcher, 00169 //calling its dirty method and seeing if it really gets dirty 00170 psym = gensym("vpatcher"); 00171 nsym = gensym("#N"); 00172 00173 if (nsym->s_thing) { 00174 if (m=zgetfn(nsym->s_thing,psym)) { 00175 //jit_cpost("got vpatcher constructor %x, %x",m,((ulong *)m)[0]); 00176 pcache=gensym("#P")->s_thing; 00177 bcache=gensym("#B")->s_thing; 00178 if (p=(*(m))(NULL,0,20,20)) { //type method assumes void * arg 00179 //if (p=typedmess(nsym->s_thing,psym,4,av)) { 00180 //jit_cpost("constructed vpatcher %x",p); 00181 typedmess((t_object *)p,gensym("dirty"),0,0L); 00182 if (!(object_attr_getchar(p,gensym("dirty")))) rv=1; 00183 //jit_cpost("patcher dirty is %d",!rv); 00184 typedmess((t_object *)p,gensym("clean"),0,0L); 00185 defer_low(p,(method)freeobject,NULL,0,NULL); 00186 } 00187 gensym("#P")->s_thing=pcache; 00188 gensym("#B")->s_thing=bcache; 00189 return rv; 00190 } 00191 } 00192 return rv; 00193 } 00194 00195 #ifdef MAC_VERSION 00196 00197 void PicAt(short picID, short slopOffset, short top, short left, short eraseFlag) 00198 { 00199 PicHandle thePicture; 00200 Rect tempRect; 00201 00202 thePicture = GetPicture(picID); 00203 #if TARGET_RT_MAC_MACHO 00204 QDGetPictureBounds(thePicture,&tempRect); 00205 #else 00206 tempRect = (*thePicture)->picFrame; 00207 #endif 00208 MacOffsetRect(&tempRect,-(tempRect.left)+left-slopOffset, 00209 -(tempRect.top)+top-slopOffset); 00210 if (eraseFlag) 00211 EraseRect(&tempRect); 00212 DrawPicture(thePicture,&tempRect); 00213 } 00214 00215 void CenterRectInRect(Rect *in, Rect *of) 00216 { 00217 short w1,w2; 00218 Rect new; 00219 00220 w1 = in->right - in->left; 00221 w2 = of->right - of->left; 00222 new.left = of->left + ((w2 - w1)/2); 00223 new.right = new.left + w1; 00224 w1 = in->bottom - in->top; 00225 w2 = of->bottom - of->top; 00226 new.top = of->top + ((w2 - w1)/2); 00227 new.bottom = new.top + w1; 00228 *in = new; 00229 } 00230 00231 void CenterWindowInMainScreen(OSType type, short idOfWindow, Rect *outRect) 00232 { 00233 Handle h; 00234 Rect *dr; 00235 GDHandle main; 00236 00237 h = (Handle) GetResource(type,idOfWindow); 00238 if (!h) 00239 return; 00240 HLock(h); 00241 main = GetMainDevice(); 00242 #if (TARGET_RT_MAC_MACHO) 00243 *outRect = *((Rect *)*h); 00244 dr = outRect; 00245 #else 00246 dr = (Rect *)*h; 00247 #endif 00248 CenterRectInRect(dr,&(*main)->gdRect); 00249 HUnlock(h); 00250 } 00251 00252 00253 void brag(void *x, short hold) 00254 { 00255 WindowPtr w; 00256 EventRecord myEvent; 00257 long a,b; 00258 CGrafPtr saveport; 00259 short vol,rsRefNum,oldResFile; 00260 long type; 00261 char name[MAX_PATH_CHARS]; 00262 00263 oldResFile = CurResFile(); 00264 sprintf(name,":jitlib"); 00265 #if !TARGET_RT_MAC_MACHO 00266 if (!locatefile_extended(name, &vol, &type, 0L, 0)) { 00267 FSSpec fs; 00268 00269 if (!path_tospec(vol, name, &fs)) { 00270 if ((rsRefNum = FSpOpenResFile(&fs, READ_PERM)) != -1) { 00271 UseResFile(rsRefNum); 00272 #else 00273 if (1) { 00274 CFBundleRef bun; 00275 long version; 00276 00277 rsRefNum = open_framework_resources(&bun); 00278 version = maxversion(); 00279 if (rsRefNum != -1) { 00280 if (1) { 00281 #endif 00282 if (GetResource('WIND',529) && GetResource('PICT',529)) 00283 { 00284 Rect newRect; 00285 00286 CenterWindowInMainScreen('WIND',529,&newRect); 00287 w = GetNewWindow(529,0L,(WindowPtr)-1L); 00288 if (!w) { 00289 error("Could not create Jitter splash window"); 00290 goto out; 00291 } 00292 #if TARGET_RT_MAC_MACHO 00293 MacMoveWindow(w,newRect.left,newRect.top,1); 00294 #endif 00295 MacShowWindow(w); 00296 SelectWindow(w); 00297 GetPort(&saveport); 00298 SetTheWindowPort(w); 00299 PicAt(529,1,0,0,FALSE); 00300 #if TARGET_API_MAC_CARBON 00301 if (maxversion()<0x0450) { 00302 EventRecord ev; 00303 WaitNextEvent(everyEvent,&ev,0,0); // carbon hack -jkc 00304 } else { 00305 EventRecord ev; 00306 EventAvail(everyEvent,&ev); 00307 } 00308 #endif 00309 00310 if (hold&&maxversion()<0x0450) { 00311 HideCursor(); 00312 a = TickCount(); 00313 while ((TickCount()>=a)&&((TickCount()-a)<60)) 00314 ; 00315 while (!Button()) 00316 ; 00317 ShowCursor(); 00318 GetNextEvent(mDownMask,&myEvent); 00319 SetPort(saveport); 00320 DisposeWindow(w); 00321 goto out; 00322 } else { 00323 a = TickCount(); 00324 while ((TickCount()>=a)&&((TickCount()-a)<65)) { 00325 if (Button()&&maxversion()<0x0450) { 00326 GetNextEvent(mDownMask,&myEvent); 00327 goto out; 00328 } 00329 } 00330 SetPort(saveport); 00331 DisposeWindow(w); 00332 goto out; 00333 } 00334 } else { 00335 goto out; 00336 } 00337 } 00338 } 00339 out: 00340 #if TARGET_RT_MAC_MACHO 00341 if (bun) 00342 close_framework_resources(bun,rsRefNum); 00343 #else 00344 UseResFile(oldResFile); 00345 if (rsRefNum) 00346 CloseResFile(rsRefNum); 00347 #endif 00348 } 00349 } 00350 00351 void addresources(void) 00352 { 00353 short vol,rsRefNum,oldResFile; 00354 long type; 00355 char name[MAX_PATH_CHARS]; 00356 00357 #if TARGET_RT_MAC_MACHO 00358 CFBundleRef bun = 0; 00359 00360 oldResFile = CurResFile(); 00361 rsRefNum = open_framework_resources(&bun); 00362 if (rsRefNum != -1) { 00363 UseResFile(rsRefNum); 00364 rescopy('WIND',529); // obsolete 00365 rescopy('PICT',529); // obsolete 00366 UseResFile(oldResFile); 00367 } 00368 close_framework_resources(bun,rsRefNum); 00369 00370 #else 00371 oldResFile = CurResFile(); 00372 sprintf(name,":jitlib"); 00373 if (!locatefile_extended(name, &vol, &type, 0L, 0)) { 00374 FSSpec fs; 00375 00376 if (!path_tospec(vol, name, &fs)) { 00377 if ((rsRefNum = FSpOpenResFile(&fs, READ_PERM)) != -1) { 00378 // if (!path_openresfile(name,vol,&rsRefNum,READ_PERM)) { 00379 UseResFile(rsRefNum); 00380 //rescopy('WIND',529); 00381 //rescopy('PICT',529); 00382 UseResFile(oldResFile); 00383 CloseResFile(rsRefNum); 00384 } 00385 } 00386 } 00387 #endif 00388 } 00389 00390 00391 #endif //MAC_VERSION 00392 00393 #ifdef WIN_VERSION 00394 VOID ResizeBragDialog(HWND hdlg); 00395 VOID ResizeBragDialog(HWND hdlg) 00396 { 00397 HBITMAP hbm; 00398 BITMAP bm; 00399 00400 hbm = LoadBitmap(_jitlib_hinst, MAKEINTRESOURCE(IDB_JITTER_SPLASH)); 00401 if (hbm) { 00402 if (GetObject(hbm, sizeof(BITMAP), (LPVOID) &bm)) { 00403 HMONITOR mon; 00404 MONITORINFO mi; 00405 mi.cbSize = sizeof (mi); 00406 mon = MonitorFromWindow(main_get_frame(), MONITOR_DEFAULTTOPRIMARY); 00407 if (mon && GetMonitorInfo(mon, &mi)) { 00408 int x, y, cx, cy; 00409 cx = bm.bmWidth; 00410 cy = bm.bmHeight; 00411 x = (mi.rcMonitor.right+mi.rcMonitor.left-cx)/2; 00412 y = (mi.rcMonitor.bottom+mi.rcMonitor.top-cy)/2; 00413 SetWindowPos(hdlg, NULL, x, y, cx, cy, SWP_NOZORDER); 00414 } 00415 } 00416 DeleteObject(hbm); 00417 } 00418 } 00419 00420 INT_PTR CALLBACK BragDialogProc(HWND hdlg, UINT msg, WPARAM wparam, LPARAM lparam); 00421 INT_PTR CALLBACK BragDialogProc(HWND hdlg, UINT msg, WPARAM wparam, LPARAM lparam) 00422 { 00423 switch (msg) 00424 { 00425 case WM_INITDIALOG: 00426 ResizeBragDialog(hdlg); 00427 SetTimer(hdlg,1,1500,NULL); 00428 return TRUE; 00429 00430 case WM_TIMER: 00431 case WM_LBUTTONDOWN: 00432 case WM_MBUTTONDOWN: 00433 case WM_RBUTTONDOWN: 00434 case WM_KEYDOWN: 00435 case WM_SYSKEYDOWN: 00436 case WM_CHAR: 00437 KillTimer(hdlg,1); 00438 EndDialog(hdlg,0); 00439 return TRUE; 00440 } 00441 return FALSE; 00442 } 00443 00444 INT_PTR CALLBACK BragDialogProcHold(HWND hdlg, UINT msg, WPARAM wparam, LPARAM lparam); 00445 INT_PTR CALLBACK BragDialogProcHold(HWND hdlg, UINT msg, WPARAM wparam, LPARAM lparam) 00446 { 00447 WINDOWINFO winfo; 00448 HBITMAP hbm; 00449 BITMAP bm; 00450 00451 switch (msg) 00452 { 00453 case WM_INITDIALOG: 00454 ResizeBragDialog(hdlg); 00455 ShowCursor(FALSE); 00456 SetCapture(hdlg); 00457 GetWindowInfo(hdlg,&winfo); 00458 SetCursorPos((winfo.rcWindow.left+winfo.rcWindow.right)/2, 00459 (winfo.rcWindow.top+winfo.rcWindow.bottom)/2); 00460 return TRUE; 00461 00462 case WM_MOUSEMOVE: 00463 //move to center of the window 00464 GetWindowInfo(hdlg,&winfo); 00465 SetCursorPos((winfo.rcWindow.left+winfo.rcWindow.right)/2, 00466 (winfo.rcWindow.top+winfo.rcWindow.bottom)/2); 00467 return TRUE; 00468 00469 case WM_LBUTTONDOWN: 00470 case WM_MBUTTONDOWN: 00471 case WM_RBUTTONDOWN: 00472 case WM_KEYDOWN: 00473 case WM_SYSKEYDOWN: 00474 case WM_CHAR: 00475 ReleaseCapture(); 00476 ShowCursor(TRUE); 00477 EndDialog(hdlg,0); 00478 return TRUE; 00479 } 00480 return FALSE; 00481 } 00482 00483 void brag(void *x, short hold) 00484 { 00485 DialogBox(_jitlib_hinst,MAKEINTRESOURCE(IDD_JITTER_SPLASH),main_get_frame(),hold?BragDialogProcHold:BragDialogProc); 00486 } 00487 00488 #endif //WIN_VERSION 00489 00490 00491 long offer_protcheck(void) 00492 { 00493 FSSpec spec; 00494 Str255 pname; 00495 CFragConnectionID connectionID; 00496 ProcPtr mainAddr; 00497 Str255 errMsg; 00498 long x = 0; 00499 char chal[16]; 00500 uchar uid[6]; 00501 uchar uid2[6]; 00502 short err; 00503 #if TARGET_API_MAC_CARBON 00504 err = FindFolder(kOnSystemDisk,kPreferencesFolderType,kDontCreateFolder,&spec.vRefNum,&spec.parID); 00505 BlockMove("\pj-offer-15-osx",spec.name,15); 00506 BlockMove("\pj-offer-15-osx",pname,15); 00507 err = GetDiskFragment(&spec, 0, 0, pname, kPrivateCFragCopy, &connectionID, (Ptr*)&mainAddr, errMsg); 00508 if (err) { 00509 //post("protcheck err %d",err); 00510 return 0; 00511 } else { 00512 short ref; 00513 long size,sum,temp,i; 00514 long count,pos; 00515 00516 err = FSpOpenDF(&spec,READ_PERM,&ref); 00517 if (err) { 00518 //post("FSpOpenDF err %d",err); 00519 return 0; 00520 } 00521 GetEOF(ref,&size); 00522 00523 if (size != 1641706) { 00524 //post("incorrect filesize: %d",size); 00525 FSClose(ref); 00526 return 0; 00527 } 00528 00529 for (i=0,sum=0,pos=0;i<32;i++) { 00530 count = 4; 00531 SetFPos(ref,fsFromStart,pos); 00532 FSRead(ref,&count,&temp); 00533 sum += temp; 00534 //post("i %d temp %d sum %d", i, temp, sum); 00535 pos = (pos+552299)%(size-4); 00536 } 00537 if (sum!=-1163725234) { 00538 //post("incorrect checksum: %d",sum); 00539 FSClose(ref); 00540 return 0; 00541 } 00542 //post("protcheck no err"); 00543 FSClose(ref); 00544 } 00545 return 1; 00546 #elif defined(WIN_VERSION) 00547 HMODULE hModule; 00548 typedef void (*JITTER_OK_FUNC)(char *, uchar *); 00549 JITTER_OK_FUNC pf; 00550 CHAR path[MAX_PATH]; 00551 HANDLE hFile; 00552 BOOL bOk; 00553 hModule = LoadLibrary("j-offer-15-win.dll"); 00554 00555 if (!hModule) { 00556 //post("Can't LoadLibrary on j-offer-15-win.dll: %d", GetLastError()); 00557 return 0; 00558 } 00559 pf = (JITTER_OK_FUNC) GetProcAddress(hModule, TEXT("jitter_ok")); 00560 if (!pf) { 00561 //post("Can't GetProcAddress on jitter_ok."); 00562 FreeLibrary(hModule); 00563 return 0; 00564 } 00565 00566 jit_rand_setseed(0); 00567 jit_rand(); 00568 00569 uid[0] = (jit_rand()>>8L); 00570 uid[1] = (jit_rand()>>8L); 00571 uid[2] = (jit_rand()>>8L); 00572 uid[3] = (jit_rand()>>8L); 00573 uid[4] = (jit_rand()>>8L); 00574 uid[5] = (jit_rand()>>8L); 00575 00576 crawly(uid,chal); 00577 00578 (*pf)(chal,uid2); 00579 00580 if (!((uid[0]==uid2[0])&& 00581 (uid[1]==uid2[1])&& 00582 (uid[2]==uid2[2])&& 00583 (uid[3]==uid2[3])&& 00584 (uid[4]==uid2[4])&& 00585 (uid[5]==uid2[5]))) 00586 { 00587 //post("jitter_ok returning false"); 00588 FreeLibrary(hModule); 00589 return 0; 00590 } 00591 00592 GetModuleFileName(hModule, path, MAX_PATH); 00593 FreeLibrary(hModule); 00594 hFile = CreateFile(path, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL); 00595 if (hFile == INVALID_HANDLE_VALUE) { 00596 //post("Can't open j-offer-15-win.dll for reading."); 00597 return 0; 00598 } 00599 else { 00600 long size,sum,temp,i; 00601 long count,pos; 00602 00603 size = GetFileSize(hFile, NULL); 00604 00605 if (size != 2438874) { 00606 //post("incorrect filesize: %d", size); 00607 CloseHandle(hFile); 00608 return 0; 00609 } 00610 00611 for (i=0,sum=0,pos=0;i<32;i++) { 00612 count = 4; 00613 SetFilePointer(hFile, pos, NULL, FILE_BEGIN); 00614 ReadFile(hFile, &temp, count, &count, NULL); 00615 sum += temp; 00616 //post("i %d temp %d sum %d", i, temp, sum); 00617 pos = (pos+552299)%(size-4); 00618 } 00619 00620 if (sum!=-1121912074) { 00621 //post("incorrect checksum %d", sum); 00622 CloseHandle(hFile); 00623 return 0; 00624 } 00625 //post("protcheck no err"); 00626 CloseHandle(hFile); 00627 } 00628 return 1; 00629 #endif //TARGET_API_MAC_CARBON 00630 } 00631 00632 void init_late(void) 00633 { 00634 if (!_initlate) { 00635 _initlate = 1; 00636 #ifdef WIN_VERSION 00637 qti_extra_flags_set(NULL,0x74747474); //require Max 4.3.1 or later 00638 // post("init_late"); 00639 if (InitializeQTML(kInitializeQTMLUseGDIFlag)==noErr) 00640 { 00641 _win_qt_init=1; 00642 InitializeQTVR(); 00643 EnterMovies(); 00644 jit_qt_component_init(); 00645 jit_qt_codec_init(); 00646 jit_qt_utils_gensymbols(); 00647 } else { 00648 error("Quicktime not installed."); 00649 post("Jitter requires Quicktime to be installed to run."); 00650 post("Please download from www.apple.com and install."); 00651 _jit_pink_roses = 0; 00652 } 00653 quittask_install((method)terminate,NULL); 00654 if (_jit_pink_roses&&_jit_javaload) 00655 jit_java_init(); 00656 #endif //WIN_VERSION 00657 } 00658 } 00659 00660 void jit_load_config(void); 00661 void jit_load_config(void) 00662 { 00663 long type=0; 00664 char filename[MAX_PATH_CHARS]; 00665 short vol; 00666 00667 strcpy(filename,"jitter-config.txt"); 00668 00669 if (!locatefile_extended(filename,&vol,&type,NULL,0)) 00670 { 00671 void *b = binbuf_new(); 00672 if (!binbuf_read(b,filename,vol,0)) 00673 binbuf_eval(b,0,NULL,NULL); 00674 binbuf_free(b); 00675 //post("found %s",filename); 00676 } else { 00677 ; //post("could not find jitter-config.txt"); 00678 } 00679 } 00680 00681 long initialize() 00682 { 00683 long err; 00684 long val=0x8523; 00685 method fn=0; 00686 long value; 00687 00688 00689 #if TARGET_RT_MAC_MACHO 00690 if (_jit_initialized) 00691 return 0; 00692 00693 _jit_initialized = true; 00694 #endif 00695 00696 #if TARGET_API_MAC_CARBON 00697 // need to do this first so we can console post during startup 00698 jit_cpost_console_init(); 00699 #endif 00700 00701 //always build our symbols 00702 jit_symbols_init(); 00703 ps_jitter = gensym("jitter"); 00704 ps_jitterCFM = gensym("jitterCFM"); 00705 #if defined(MAC_VERSION) && !(TARGET_RT_MAC_MACHO) 00706 if (!object_attr_getvalueof) { 00707 post("Jitter requires Max/MSP 4.5.5 or higher"); 00708 return -1; 00709 } 00710 #endif 00711 00712 // 1. are we in runtime? 00713 _jit_pink_roses = maxruntime(); 00714 //_jit_pink_roses = 1; 00715 //jit_cpost("jitlib: initialize 03: runtime %d",_jit_pink_roses); 00716 00717 // 2. are we authorized? 00718 00719 #ifdef JITTER_AUTH_PRE_5_1 //legacy cp code 00720 /* commenting out to avoid confusion, but leaving for future generations 00721 #ifdef JIT_PROT_ORIGINAL 00722 if ((!_jit_pink_roses)&&(fn=(method)gensym("%7&[n3e")->s_thing)) 00723 #else // JIT_PROT_ORIGINAL: new token check for Jitter 1.5 00724 #if TARGET_RT_MAC_MACHO 00725 fn = (method)gensym("%dpf!!2ezx")->s_thing; 00726 #else //TARGET_RT_MAC_MACHO 00727 #if MAC_VERSION 00728 Gestalt('max2',&value); 00729 if (value == 'max2') { // we are in MACHO host 00730 post("Jitter CFM support loaded"); 00731 post("warning: Jitter CFM objects are not guaranteed to work in Max 4.6 and higher"); 00732 _cfm_in_ub = 1; 00733 } 00734 00735 #endif //MAC_VERSION 00736 { 00737 // Windows and CFM use the original symbol 00738 fn = (method)gensym("%943f}>ee")->s_thing; 00739 } 00740 #endif //TARGET_RT_MAC_MACHO 00741 #endif //JIT_PROT_ORIGINAL 00742 */ 00743 #else //JITTER_AUTH_PRE_5_1 00744 fn = (method)gensym("%x9*!gv?Z")->s_thing; 00745 #endif //JITTER_AUTH_PRE_5_1 00746 00747 if ((!_jit_pink_roses)&&fn) 00748 { 00749 (*fn)(&val); 00750 if (val==1) { 00751 post("Jitter is in demo mode"); 00752 _jit_pink_roses = 1; 00753 offer_protcheck(); //prevent 60 day demo 00754 gensym("###succotash")->s_thing = (t_object *)1; // for auth menu item 00755 } else if (val==0){ 00756 _jit_pink_roses = 1; 00757 } 00758 } 00759 00760 // 3. are we in demo mode? 00761 if (!_jit_pink_roses) { //try loading demo 00762 if (_jit_pink_roses=offer_protcheck()) { 00763 post("Jitter %s is in demo mode", _jit_version_str); 00764 gensym("###succotash")->s_thing = (t_object *)1; // for auth menu item 00765 } else 00766 post("Jitter demo period has expired"); 00767 } 00768 00769 if (!_jit_pink_roses) { 00770 error("Jitter is not authorized"); 00771 _jit_nosplash = 1; 00772 } else { 00773 post("Jitter %s installed", _jit_version_str); 00774 } 00775 00776 #ifdef JIT_TEST_NO_AUTHORIZATION 00777 _jit_pink_roses = FALSE; 00778 #endif 00779 00780 00781 #ifdef MAC_VERSION 00782 jit_altivec_init(); 00783 #endif 00784 if (err = jit_object_init()) { 00785 error("Jitter could not load %d", err); 00786 } else { 00787 #ifdef MAC_VERSION 00788 //addresources(); obsolete 00789 #endif 00790 jit_load_config(); 00791 //if (!_jit_nosplash) 00792 // defer_low(gensym("jit")->s_thing,(method)brag,0L,0,0L); 00793 #ifndef WIN_VERSION //else happens in init late 00794 if (_jit_pink_roses&&_jit_javaload) 00795 jit_java_init(); 00796 #endif 00797 } 00798 00799 return 0; //always succeed 00800 } 00801 00802 #if !TARGET_RT_MAC_MACHO 00803 00804 void main(void) 00805 { 00806 // jit_object_init(); 00807 } 00808 00809 #endif // TARGET_RT_MAC_MACHO 00810 00811 void terminate(void) 00812 { 00813 // jit_object_shutdown(); 00814 00815 #ifdef WIN_VERSION //win_todo 00816 if (_win_qt_init) { 00817 jit_qt_codec_free(); 00818 ExitMovies(); 00819 TerminateQTVR(); 00820 TerminateQTML(); 00821 } 00822 #else 00823 jit_qt_codec_free(); 00824 ExitMovies(); 00825 #endif //WIN_VERSION 00826 } 00827 00828 #ifndef WIN_VERSION //win_todo 00829 extern _jit_cord_pattern; 00830 RGBColor optc = {0x0000,0xFFFF,0x0000}; 00831 RGBColor optc2 = {0xFFFF,0x0000,0xFFFF}; 00832 RGBColor black = {0x0000,0x0000,0x0000}; 00833 00834 void jit_matrix_optdraw(void *x, Patchline *l); 00835 void jit_matrix_optdraw(void *x, Patchline *l) 00836 { 00837 short i,off; 00838 RGBColor saveFore, saveBack,rgb; 00839 Pattern p; 00840 00841 GetForeColor(&saveFore); 00842 GetBackColor(&saveBack); 00843 00844 if (l->l_selected) 00845 RGBForeColor(&optc2); // do something distinctive when it is selected 00846 else if (l->l_color) { 00847 box_getcolor(l->l_box1,l->l_color-1,&rgb); // pay attention to patch cord color, default black 00848 RGBForeColor(&rgb); 00849 } 00850 RGBBackColor(&optc); 00851 00852 if (_jit_cord_pattern>=0) 00853 PenSize(2,2); // optional patch cords must be 2x2 for now 00854 else 00855 PenSize(3,3); 00856 00857 if (_jit_cord_pattern>=1) { 00858 GetIndPattern(&p, sysPatListID, _jit_cord_pattern ); /* system pattern */ 00859 PenPat(&p); 00860 } 00861 00862 //draw fatty 00863 if (l->l_selected) 00864 RGBForeColor(&optc2); // do something distinctive when it is selected 00865 else if (l->l_color) { 00866 box_getcolor(l->l_box1,l->l_color-1,&rgb); // pay attention to patch cord color, default black 00867 RGBForeColor(&black); 00868 } else { 00869 rgb = optc; 00870 } 00871 00872 MoveTo(l->l_x[0], l->l_y[0]); 00873 if (l->l_segments > 1) { 00874 for (i=1; i <= l->l_segments; i++) 00875 LineTo(l->l_x[i],l->l_y[i]); 00876 } else if (l->l_segments) 00877 LineTo(l->l_x[1], l->l_y[1]); 00878 00879 if (_jit_cord_pattern<=0) { 00880 off = (_jit_cord_pattern<0) ? 1 : 0; 00881 //draw skinny 00882 PenSize(1,1); 00883 RGBForeColor(&rgb); 00884 00885 MoveTo(l->l_x[0]+off, l->l_y[0]+off); 00886 if (l->l_segments > 1) { 00887 for (i=1; i <= l->l_segments; i++) 00888 LineTo(l->l_x[i]+off,l->l_y[i]+off); 00889 } else if (l->l_segments) 00890 LineTo(l->l_x[1]+off, l->l_y[1]+off); 00891 } 00892 00893 l->l_flags |= F_DRAWN; // set drawn flag 00894 00895 RGBForeColor(&saveFore); // restore colors & pen 00896 RGBBackColor(&saveBack); 00897 PenNormal(); 00898 PenSize(1,1); 00899 } 00900 00901 RGBColor txoptc = {0x2222,0x8888,0xFFFF}; 00902 RGBColor txoptc2 = {0xFFFF,0x0000,0xFFFF}; 00903 00904 void jit_gl_texture_optdraw(void *x, Patchline *l); 00905 void jit_gl_texture_optdraw(void *x, Patchline *l) 00906 { 00907 short i,off; 00908 RGBColor saveFore, saveBack,rgb; 00909 Pattern p; 00910 00911 GetForeColor(&saveFore); 00912 GetBackColor(&saveBack); 00913 00914 if (l->l_selected) 00915 RGBForeColor(&txoptc2); // do something distinctive when it is selected 00916 else if (l->l_color) { 00917 box_getcolor(l->l_box1,l->l_color-1,&rgb); // pay attention to patch cord color, default black 00918 RGBForeColor(&rgb); 00919 } 00920 RGBBackColor(&txoptc); 00921 00922 if (_jit_cord_pattern>=0) 00923 PenSize(2,2); // optional patch cords must be 2x2 for now 00924 else 00925 PenSize(3,3); 00926 00927 if (_jit_cord_pattern>=1) { 00928 GetIndPattern(&p, sysPatListID, _jit_cord_pattern ); /* system pattern */ 00929 PenPat(&p); 00930 } 00931 00932 //draw fatty 00933 if (l->l_selected) 00934 RGBForeColor(&txoptc2); // do something distinctive when it is selected 00935 else if (l->l_color) { 00936 box_getcolor(l->l_box1,l->l_color-1,&rgb); // pay attention to patch cord color, default black 00937 RGBForeColor(&black); 00938 } else { 00939 rgb = txoptc; 00940 } 00941 00942 MoveTo(l->l_x[0], l->l_y[0]); 00943 if (l->l_segments > 1) { 00944 for (i=1; i <= l->l_segments; i++) 00945 LineTo(l->l_x[i],l->l_y[i]); 00946 } else if (l->l_segments) 00947 LineTo(l->l_x[1], l->l_y[1]); 00948 00949 if (_jit_cord_pattern<=0) { 00950 off = (_jit_cord_pattern<0) ? 1 : 0; 00951 //draw skinny 00952 PenSize(1,1); 00953 RGBForeColor(&rgb); 00954 00955 MoveTo(l->l_x[0]+off, l->l_y[0]+off); 00956 if (l->l_segments > 1) { 00957 for (i=1; i <= l->l_segments; i++) 00958 LineTo(l->l_x[i]+off,l->l_y[i]+off); 00959 } else if (l->l_segments) 00960 LineTo(l->l_x[1]+off, l->l_y[1]+off); 00961 } 00962 00963 l->l_flags |= F_DRAWN; // set drawn flag 00964 00965 RGBForeColor(&saveFore); // restore colors & pen 00966 RGBBackColor(&saveBack); 00967 PenNormal(); 00968 PenSize(1,1); 00969 } 00970 00971 #endif 00972 00973 00974 #pragma mark - 00975 // -------------------------------------------------------------------------------- 00976 // 00977 00978 long jit_method_true(void *x) 00979 { 00980 return 1; 00981 } 00982 00983 long jit_method_false(void *x) 00984 { 00985 return 0; 00986 } 00987 00988 #pragma mark - 00989 // -------------------------------------------------------------------------------- 00990 // 00991 00992 t_jit_err jit_class_init(void) 00993 { 00994 _jit_class_class = jit_class_new("jit_class",(method)jit_class_new,(method)jit_class_free, 00995 sizeof(t_jit_class),A_CANT,0L); //A_CANT = untyped 00996 00997 if (!_jit_class_class) post("couldn't allocate memory for class jit_class"); 00998 00999 return JIT_ERR_NONE; 01000 } 01001 01002 /** 01003 * Creates a new class with the name specified by the name argument. 01004 * 01005 * @ingroup classmod 01006 * 01007 * @param name class name 01008 * @param mnew class constructor 01009 * @param mfree class destructor 01010 * @param size object struct size in bytes 01011 * @param ... type signature for the constructor in the standard 01012 * Max type list format (see Chapter 3 of the Writing 01013 * Externals in Max document for more information) 01014 * @warning In order for the Jitter class to be exposed to 01015 * JavaScript and Java, it is important that the constructor is typed, 01016 * even if no arguments are provided--i.e. do not use the older strategy 01017 * of defining Jitter constructors as private and untyped with A_CANT. 01018 * 01019 * @return class pointer to be used in other class functions 01020 * 01021 */ 01022 void *jit_class_new(char *name, method mnew, method mfree, long size, ...) 01023 { 01024 long type; 01025 void *c; 01026 01027 #if TARGET_RT_MAC_MACHO 01028 initialize(); 01029 #endif 01030 01031 //there might be a bit of a problem here with short/long 01032 type = *((long *)(((char *)(&size))+4)); 01033 c = class_new(name,mnew,mfree,size,NULL/*menu*/,(short)type,*((t_stack_splat *)(((char *)(&size))+8))); 01034 #if defined(MAC_VERSION) && (!TARGET_RT_MAC_MACHO) 01035 class_extra_store(c,gensym("runtime_architecture"),(t_object *)gensym("CFM")); 01036 #endif 01037 class_addmethod(c,(method)jit_method_true,"class_jitter",A_CANT); 01038 class_addmethod(c,(method)jit_object_importattrs,"importattrs",A_GIMME); 01039 class_addmethod(c,(method)jit_object_exportattrs,"exportattrs",A_GIMME); 01040 return c; 01041 } 01042 01043 01044 /** 01045 * Adds a named method to a class. 01046 * 01047 * @ingroup classmod 01048 * 01049 * @param c class pointer 01050 * @param m function called when method is invoked 01051 * @param name method name 01052 * @param ... type signature for the method in the standard 01053 * Max type list format (see Chapter 3 of the Writing 01054 * Externals in Max document for more information) 01055 * 01056 * @return t_jit_err error code 01057 * 01058 */ 01059 t_jit_err jit_class_addmethod(void *c, method m, char *name, ...) 01060 { 01061 t_max_err err; 01062 err = class_addmethod((t_class *)c,m,name,*((t_stack_splat *)(((char *)(&name))+4))); 01063 return jit_err_from_max_err(err); 01064 } 01065 01066 /** 01067 * Adds an attribute to a class. 01068 * 01069 * @ingroup classmod 01070 * 01071 * @param c class pointer 01072 * @param attr attribute object 01073 * 01074 * @return t_jit_err error code 01075 * 01076 */ 01077 t_jit_err jit_class_addattr(void *c,t_jit_object *attr) 01078 { 01079 t_max_err err; 01080 err = class_addattr((t_class *)c,attr); 01081 return jit_err_from_max_err(err); 01082 } 01083 01084 /** 01085 * Adds an adornment to a class. 01086 * Adornments provide additional state and behavior to 01087 * a class. This is most commonly used for the jit_mop 01088 * adornment. 01089 * 01090 * @ingroup classmod 01091 * 01092 * @param c class pointer 01093 * @param o object to use as adornment 01094 * 01095 * @return t_jit_err error code 01096 * 01097 */ 01098 t_jit_err jit_class_addadornment(void *c,t_jit_object *o) 01099 { 01100 t_max_err err; 01101 err = class_addadornment((t_class *)c,o); 01102 return jit_err_from_max_err(err); 01103 } 01104 01105 /** 01106 * Compares object's class name with the name provided. 01107 * 01108 * @ingroup objectmod 01109 * 01110 * @param x object pointer 01111 * @param name name to compare with class name 01112 * 01113 * @return 1 if equal, 0 if not equal 01114 * 01115 */ 01116 long jit_object_classname_compare(void *x, t_symbol *name) 01117 { 01118 return (name&&(name==jit_object_classname(x))); 01119 } 01120 01121 /** 01122 * Retrieves an adornment from a class. 01123 * Adornments provide additional state and behavior to 01124 * a class. This is most commonly used for the jit_mop 01125 * adornment. 01126 * 01127 * @ingroup classmod 01128 * 01129 * @param c class pointer 01130 * @param classname classname of adornment to retrieve 01131 * 01132 * @return t_jit_err error code 01133 * 01134 */ 01135 void *jit_class_adornment_get(void *c,t_symbol *classname) 01136 { 01137 return class_adornment_get((t_class *)c,classname); 01138 } 01139 01140 /** 01141 * Frees a class. 01142 * 01143 * @warning This function is not typically used outside of jitlib. 01144 * 01145 * @ingroup classmod 01146 * 01147 * @param c class pointer 01148 * 01149 * @return t_jit_err error code 01150 * 01151 */ 01152 t_jit_err jit_class_free(void *c) 01153 { 01154 t_max_err err; 01155 err = class_free((t_class *)c); 01156 return jit_err_from_max_err(err); 01157 } 01158 01159 /** 01160 * Retrieves the name of a class 01161 * 01162 * @ingroup classmod 01163 * 01164 * @param c class pointer 01165 * 01166 * @return t_symbol pointer containing name of class 01167 * 01168 */ 01169 t_symbol *jit_class_nameget(void *c) 01170 { 01171 return class_nameget((t_class *)c); 01172 } 01173 01174 /** 01175 * Compares name of class with the name provided. 01176 * 01177 * @ingroup classmod 01178 * 01179 * @param c class pointer 01180 * @param name name to compare with class name 01181 * 01182 * @return 1 if equal, 0 if not equal 01183 * 01184 */ 01185 long jit_class_symcompare(void *c, t_symbol *name) 01186 { 01187 return (name&&(jit_class_nameget(c)==name)); 01188 } 01189 01190 /** 01191 * Registers class in the class registry. 01192 * 01193 * @ingroup classmod 01194 * 01195 * @param c class pointer 01196 * 01197 * @return t_jit_err error code 01198 * 01199 */ 01200 t_jit_err jit_class_register(void *c) 01201 { 01202 t_max_err err; 01203 err = class_register(CLASS_JITTER,(t_class *)c); 01204 return jit_err_from_max_err(err); 01205 } 01206 01207 /** 01208 * Retrieves method function pointer for named method. 01209 * 01210 * @ingroup classmod 01211 * 01212 * @param c class pointer 01213 * @param methodname method name 01214 * 01215 * @return method function pointer. 01216 * 01217 */ 01218 method jit_class_method(void *c, t_symbol *methodname) 01219 { 01220 return class_method((t_class *)c,methodname); 01221 } 01222 01223 /** 01224 * Retrieves messlist entry for named method. 01225 * 01226 * @ingroup classmod 01227 * 01228 * @param c class pointer 01229 * @param methodname method name 01230 * 01231 * @return t_messlist pointer. 01232 * 01233 */ 01234 t_messlist *jit_class_mess(t_jit_class *c, t_symbol *methodname) 01235 { 01236 return class_mess((t_class *)c,methodname); 01237 } 01238 01239 /** 01240 * Compares symbol name with name provided. 01241 * 01242 * @ingroup attrmod 01243 * 01244 * @param x attribute object pointer 01245 * @param name attribute name 01246 * 01247 * @return 1 if equal, 0 if not equal 01248 * 01249 */ 01250 long jit_attr_symcompare(void *x, t_symbol *name) 01251 { 01252 return (name == object_method(x,_jit_sym_getname)); 01253 } 01254 01255 method jit_class_attr_method(t_jit_class *c, t_symbol *methodname, void **attr) 01256 { 01257 long get=0; 01258 return class_attr_method(c,methodname,attr,&get); 01259 } 01260 01261 /** 01262 * Retrieves attribute pointer associated with name provided. 01263 * 01264 * @ingroup classmod 01265 * 01266 * @param c class pointer 01267 * @param attrname attribute name 01268 * 01269 * @return attribute object pointer 01270 * 01271 */ 01272 void *jit_class_attr_get(void *c, t_symbol *attrname) 01273 { 01274 return class_attr_get((t_class *)c,attrname); 01275 } 01276 01277 /** 01278 * Retrieves class pointer associated with name provided. 01279 * 01280 * @ingroup classmod 01281 * 01282 * @param classname class name 01283 * 01284 * @return class pointer 01285 * 01286 */ 01287 void *jit_class_findbyname(t_symbol *classname) 01288 { 01289 return class_findbyname(CLASS_JITTER,classname); 01290 } 01291 01292 /** 01293 * Adds a typed wrapper method to a class. 01294 * Typed wrappers typically are used when there is an existing 01295 * private, untyped method defined for a Jitter class, but it is 01296 * desirable to expose the method to language bindings which 01297 * require a typed interface--e.g. Java or JavaScript. 01298 * 01299 * @ingroup classmod 01300 * 01301 * @param c class pointer 01302 * @param m function called when method is invoked 01303 * @param name method name 01304 * @param ... type signature for the method in the standard 01305 * Max type list format (see Chapter 3 of the Writing 01306 * Externals in Max document for more information) 01307 * 01308 * @return t_jit_err error code 01309 * 01310 */ 01311 t_jit_err jit_class_addtypedwrapper(void *c, method m, char *name, ...) 01312 { 01313 t_max_err err; 01314 err = class_addtypedwrapper((t_class *)c,m,name,*((t_stack_splat *)(((char *)(&name))+4))); 01315 return jit_err_from_max_err(err); 01316 } 01317 01318 /** 01319 * Retrieves typed wrapper messlist pointer associated with name provided. 01320 * 01321 * @ingroup classmod 01322 * 01323 * @param c class pointer 01324 * @param s name 01325 * 01326 * @return t_messlist pointer 01327 * 01328 */ 01329 t_messlist *jit_class_typedwrapper_get(void *c, t_symbol *s) 01330 { 01331 return class_typedwrapper_get((t_class *)c,s); 01332 } 01333 01334 // the argsafe implementation could be more elegant, but since it is 01335 // wrapped with accessor functions, can always change implementation 01336 01337 /** 01338 * Marks a method as safe to call as an attribute style argument. 01339 * 01340 * @warning It is important that no argument settable method causes 01341 * any output into the patcher, or else it could lead to a 01342 * crash, or other undesired behavior. 01343 * 01344 * @ingroup classmod 01345 * 01346 * @param c class pointer 01347 * @param argname name as used via argument 01348 * @param methodname name of method to map the argument name to 01349 * 01350 * @return t_jit_err error code 01351 * 01352 */ 01353 t_jit_err jit_class_method_addargsafe(void *c, char *argname, char *methodname) 01354 { 01355 t_max_err err; 01356 char str[255]; 01357 sprintf(str,"%s_argsafe",argname); 01358 err = class_extra_store((t_class *)c,gensym(str),(t_object *)gensym(methodname)); 01359 return jit_err_from_max_err(err); 01360 } 01361 01362 /** 01363 * Checks to see if symbol is safe to call as an attribute style argument. 01364 * 01365 * @ingroup classmod 01366 * 01367 * @param c class pointer 01368 * @param s name as used via argument 01369 * 01370 * @return If successful, name of method to map the argument name to. 01371 * Otherwise, NULL. 01372 * 01373 */ 01374 t_symbol *jit_class_method_argsafe_get(void *c, t_symbol *s) 01375 { 01376 char str[255]; 01377 sprintf(str,"%s_argsafe",s->s_name); 01378 return (t_symbol *) class_extra_lookup((t_class *)c,gensym(str)); 01379 } 01380 01381 /** 01382 * Checks to see if symbol is safe to call as an attribute style argument. 01383 * 01384 * @ingroup objectmod 01385 * 01386 * @param x object pointer 01387 * @param s name as used via argument 01388 * 01389 * @return If successful, name of method to map the argument name to. 01390 * Otherwise, NULL. 01391 * 01392 */ 01393 t_symbol *jit_object_method_argsafe_get(void *x, t_symbol *s) 01394 { 01395 return jit_class_method_argsafe_get(jit_object_class(x),s); 01396 } 01397 01398 01399 #pragma mark - 01400 // -------------------------------------------------------------------------------- 01401 // 01402 01403 /** 01404 * Allocates object struct memory. 01405 * 01406 * This function is used within an object's constructor. 01407 * 01408 * @ingroup obejctfun 01409 * 01410 * @param c class pointer 01411 * 01412 * @return If successful, an object pointer equal in size to that 01413 * defined in {@link jit_class_new}. Otherwise, NULL. 01414 * 01415 * @warning This memory is not cleared to zero, so it is important 01416 * that you explicitly initialize as necessary. It is not 01417 * safe to simply zero out all of your object struct as the 01418 * t_jit_object header contains necessary data. if you wish 01419 * to zero out your object struct, do so beginning at the 01420 * sizeof(t_jit_object) byte offset. 01421 * 01422 */ 01423 void *jit_object_alloc(void *c) 01424 { 01425 return object_alloc((t_class *)c); 01426 } 01427 01428 /** 01429 * Instantiates an object specified by class name. 01430 * 01431 * This function may used to create instances of any Jitter object. 01432 * 01433 * @ingroup objectmod 01434 * 01435 * @param classname class name 01436 * @param ... untyped arguments passed on to the constructor 01437 * @warning It is important to know any necessary arguments for untyped 01438 * constructors such as those used by jit_matrix or jit_attr_offset. 01439 * 01440 * @return If successful, a valid object pointer. Otherwise, NULL. 01441 * 01442 */ 01443 void *jit_object_new(t_symbol *classname, ...) 01444 { 01445 t_object *o=NULL; 01446 01447 #if TARGET_RT_MAC_MACHO 01448 initialize(); 01449 #endif 01450 01451 if (!_jit_pink_roses) { 01452 01453 #ifdef WIN_VERSION // don't let these instantiate if QT is not installed 01454 if (_win_qt_init) 01455 #endif 01456 hashtab_lookup(_jcs_hash,classname,&o); 01457 01458 01459 if (!o) goto out; //cp 01460 } 01461 01462 if (!_initlate) 01463 init_late(); 01464 ////////////////////////////////////////////////////////// 01465 01466 return object_new(CLASS_JITTER,classname,*((t_stack_splat *)(((char *)(&classname))+4))); 01467 out: 01468 //post("jit_object_new: could not create: %s", classname->s_name); 01469 return NULL; 01470 } 01471 01472 /** 01473 * Calls an object method specified by method name. 01474 * 01475 * This operation is untyped, and the contents of the stack following 01476 * the method name argument are blindly passed to the method called. 01477 * 01478 * @ingroup objectmod 01479 * 01480 * @param x object pointer 01481 * @param s method name 01482 * @param ... untyped arguments passed on to the method 01483 * @warning It is important to know any necessary arguments for untyped 01484 * constructors such as those used by jit_matrix or jit_attr_offset. 01485 * 01486 * @return method dependent, but uses void * as a super type. 01487 * 01488 */ 01489 void *jit_object_method(void *x, t_symbol *s, ...) 01490 { 01491 return object_method(x,s,*((t_stack_splat *)(((char *)(&s))+4))); 01492 } 01493 01494 /** 01495 * Calls a typed object method specified by method name. 01496 * This operation only supports methods which are typed--i.e. it cannot 01497 * be used to call private, untyped A_CANT methods. 01498 * 01499 * @ingroup objectmod 01500 * 01501 * @param x object pointer 01502 * @param s method name 01503 * @param ac argument count 01504 * @param av argument vector 01505 * @param rv return value for A_GIMMEBACK methods 01506 * 01507 * @return method dependent, but uses void * as a super type. 01508 * 01509 */ 01510 void *jit_object_method_typed(void *x, t_symbol *s, long ac, t_atom *av, t_atom *rv) 01511 { 01512 return (void *)object_method_typed(x,s,ac,av,rv); 01513 } 01514 01515 /** 01516 * Retrieves an object method specified by method name. 01517 * 01518 * @ingroup objectmod 01519 * 01520 * @param x object pointer 01521 * @param s method name 01522 * 01523 * @return method 01524 * 01525 */ 01526 method jit_object_getmethod(void *x, t_symbol *s) 01527 { 01528 return object_getmethod(x,s); 01529 } 01530 01531 /** 01532 * Determines if an object attribute is user settable. 01533 * 01534 * @ingroup objectmod 01535 * 01536 * @param x object pointer 01537 * @param s attribute name 01538 * 01539 * @return 1 if settable, 0 if not settable 01540 * 01541 */ 01542 long jit_object_attr_usercanset(void *x, t_symbol *s) 01543 { 01544 return object_attr_usercanset(x,s); 01545 } 01546 01547 /** 01548 * Determines if an object attribute is user gettable. 01549 * 01550 * @ingroup objectmod 01551 * 01552 * @param x object pointer 01553 * @param s attribute name 01554 * 01555 * @return 1 if gettable, 0 if not gettable 01556 * 01557 */ 01558 long jit_object_attr_usercanget(void *x, t_symbol *s) 01559 { 01560 return object_attr_usercanget(x,s); 01561 } 01562 01563 /** 01564 * Retrieves an object's attribute pointer specified by attribute name. 01565 * 01566 * @ingroup objectmod 01567 * 01568 * @param x object pointer 01569 * @param attrname attribute name 01570 * 01571 * @return attribute object pointer 01572 * 01573 */ 01574 void *jit_object_attr_get(void *x, t_symbol *attrname) 01575 { 01576 return object_attr_get(x,attrname); 01577 } 01578 01579 /** 01580 * Frees an object. 01581 * 01582 * @ingroup objectmod 01583 * 01584 * @param x object pointer 01585 * 01586 * @return t_jit_err error code 01587 * 01588 */ 01589 t_jit_err jit_object_free(void *x) 01590 { 01591 t_max_err err; 01592 err = object_free(x); 01593 return jit_err_from_max_err(err); 01594 } 01595 01596 /** 01597 * Retrieves an object's class name. 01598 * 01599 * @ingroup objectmod 01600 * 01601 * @param x object pointer 01602 * 01603 * @return class name t_symbol pointer 01604 * 01605 */ 01606 t_symbol *jit_object_classname(void *x) 01607 { 01608 return object_classname(x); 01609 } 01610 01611 /** 01612 * Retrieves an object's class pointer. 01613 * 01614 * @ingroup objectmod 01615 * 01616 * @param x object pointer 01617 * 01618 * @return class pointer 01619 * 01620 */ 01621 void *jit_object_class(void *x) 01622 { 01623 return object_class(x); 01624 } 01625 01626 t_jit_err jit_object_init(void) 01627 { 01628 if (!_jit_object_init) { 01629 // free hipno classes 01630 _jcs_hash = hashtab_new(0); 01631 hashtab_store(_jcs_hash,_jit_sym_jit_attr_offset,(t_object *)TRUE); 01632 hashtab_store(_jcs_hash,_jit_sym_jit_attr_offset_array,(t_object *)TRUE); 01633 hashtab_store(_jcs_hash,gensym("jit_attr_filter_clip"),(t_object *)TRUE); 01634 hashtab_store(_jcs_hash,_jit_sym_jit_linklist,(t_object *)TRUE); 01635 hashtab_store(_jcs_hash,_jit_sym_jit_mop,(t_object *)TRUE); 01636 hashtab_store(_jcs_hash,gensym("jit_mop_io"),(t_object *)TRUE); 01637 hashtab_store(_jcs_hash,gensym("jit_alphablend"),(t_object *)TRUE); 01638 hashtab_store(_jcs_hash,gensym("jit_kernel"),(t_object *)TRUE); 01639 hashtab_store(_jcs_hash,gensym("jit_matrix"),(t_object *)TRUE); 01640 hashtab_store(_jcs_hash,gensym("jit_op"),(t_object *)TRUE); 01641 hashtab_store(_jcs_hash,gensym("jit_pwindow"),(t_object *)TRUE); 01642 hashtab_store(_jcs_hash,gensym("jit_xfade"),(t_object *)TRUE); 01643 hashtab_store(_jcs_hash,gensym("jit_pack"),(t_object *)TRUE); 01644 hashtab_store(_jcs_hash,gensym("jit_unpack"),(t_object *)TRUE); 01645 hashtab_store(_jcs_hash,gensym("jit_fill"),(t_object *)TRUE); 01646 hashtab_store(_jcs_hash,gensym("jit_spill"),(t_object *)TRUE); 01647 hashtab_store(_jcs_hash,gensym("jit_iter"),(t_object *)TRUE); 01648 hashtab_store(_jcs_hash,gensym("jit_qt_movie"),(t_object *)TRUE); 01649 hashtab_store(_jcs_hash,gensym("jit_uyvy2ayuv"),(t_object *)TRUE); 01650 hashtab_store(_jcs_hash,gensym("jit_ayuv2uyvy"),(t_object *)TRUE); 01651 hashtab_store(_jcs_hash,gensym("jit_ayuv2argb"),(t_object *)TRUE); 01652 hashtab_store(_jcs_hash,gensym("jit_uyvy2argb"),(t_object *)TRUE); 01653 hashtab_store(_jcs_hash,gensym("tap_jit_sum"),(t_object *)TRUE); 01654 hashtab_store(_jcs_hash,gensym("tap_jit_proximity"),(t_object *)TRUE); 01655 hashtab_store(_jcs_hash,gensym("tap_jit_kernel"),(t_object *)TRUE); 01656 hashtab_store(_jcs_hash,gensym("tap_jit_colortrack"),(t_object *)TRUE); 01657 hashtab_store(_jcs_hash,gensym("tap_jit_ali"),(t_object *)TRUE); 01658 01659 _jit_object_init=1; 01660 jit_rand_setseed(0); 01661 jit_rand(); //once for good measure (first 2 times around it's duplicated) 01662 _jit_mess_nonmethod.m_sym = gensym("nonmethod"); 01663 _jit_mess_nonmethod.m_fun = (method)jit_method_false; 01664 _jit_mess_freemethod.m_sym = gensym("free"); 01665 _jit_mess_freemethod.m_fun = (method)jit_object_free; 01666 jit_class_init(); //register class class manually 01667 jit_linklist_init(); //register list class manually 01668 //previously we manually added these classes, but 01669 //now that we are actualling using the obex classes, 01670 //we can register with jit_class_register 01671 //(i.e. no chicken/egg problem, as before) 01672 jit_class_register(_jit_class_class); 01673 jit_class_register(_jit_linklist_class); 01674 01675 //now register other classes 01676 //later some of these should move to better places 01677 jit_attr_init(); 01678 jit_max_init(); 01679 jit_matrix_init(); 01680 jit_matrix_wrapper_init(); 01681 jit_mop_init(); 01682 jit_kernel_init(); 01683 jit_la_mult_init(); 01684 jit_la_uppertri_init(); 01685 jit_la_trace_init(); 01686 jit_la_diagproduct_init(); 01687 jit_la_determinant_init(); 01688 jit_la_inverse_init(); 01689 if (_jit_pink_roses) 01690 jit_gl_init(); 01691 jit_parallel_utils_init(); 01692 jit_op_init(); 01693 jit_tree_init(); 01694 jit_expr_init(); 01695 jit_functor_init(); 01696 jit_listener_init(); 01697 jit_charset_init(); 01698 jit_xml_init(); 01699 jit_uyvy_init(); 01700 #ifndef WIN_VERSION //win_todo 01701 EnterMovies(); 01702 jit_qt_movie_init(); 01703 jit_qt_record_init(); 01704 jit_qt_component_init(); 01705 jit_qt_codec_init(); 01706 jit_qt_utils_gensymbols(); 01707 //Max stuff 01708 01709 #ifdef USE_ALTURA 01710 patchline_addmess(_jit_sym_jit_matrix,(method)jit_matrix_optdraw); 01711 patchline_addmess(gensym("jit_gl_texture"),(method)jit_gl_texture_optdraw); 01712 #endif 01713 01714 #else 01715 // IMPORTANT!!! ON WINDOWS ALL QT CALLS 01716 // MUST BE MADE IN init_late(). CURRENTLY 01717 // IT IS SAFE TO CALL jit_qt_movie_init() ANY record_init() 01718 // AS THEY DON'T MAKE ANY QT CALLS. IF THIS 01719 // CHANGES, WE NEED TO MOVE TO init_late() 01720 //InitializeQTVR(); 01721 //EnterMovies(); 01722 jit_qt_movie_init(); 01723 jit_qt_record_init(); 01724 _initlate=0; 01725 defer_low(gensym("jit")->s_thing,(method)init_late,NULL,0,NULL); 01726 #endif //WIN_VERSION 01727 } 01728 01729 return JIT_ERR_NONE; 01730 } 01731 01732 //a general mechanism for multiply referenced named objects 01733 01734 /** 01735 * Registers an object in the named object registry. 01736 * 01737 * @ingroup objectmod 01738 * 01739 * @param x object pointer 01740 * @param s object name 01741 * 01742 * @return object pointer 01743 * 01744 * @warning It is important to use the object pointer returned 01745 * by jit_object_register, since if there is an existing 01746 * object with the same name and class, it could free 01747 * the input object and pass back a reference to the 01748 * previously defined object. 01749 * 01750 */ 01751 void *jit_object_register(void *x, t_symbol *s) 01752 { 01753 // name argument is now before object argument 01754 return object_register(REGOB_NAMESPACE_JITTER,s,x); 01755 } 01756 01757 /** 01758 * Unregisters an object from the named object registry. 01759 * 01760 * @ingroup objectmod 01761 * 01762 * @param x object pointer 01763 * 01764 * @return t_jit_err error code 01765 * 01766 */ 01767 t_jit_err jit_object_unregister(void *x) 01768 { 01769 01770 t_max_err err; 01771 err = object_unregister(x); 01772 return jit_err_from_max_err(err); 01773 } 01774 01775 /** 01776 * Retrieves a registered object associated with name. 01777 * 01778 * @ingroup objectmod 01779 * 01780 * @param s registered name 01781 * 01782 * @return If successful, object pointer. Otherwise NULL. 01783 * 01784 */ 01785 void *jit_object_findregistered(t_symbol *s) 01786 { 01787 return object_findregistered(REGOB_NAMESPACE_JITTER,s); 01788 } 01789 01790 /** 01791 * Retrieves a registered object's name. 01792 * 01793 * @ingroup objectmod 01794 * 01795 * @param x object pointer 01796 * 01797 * @return If successful, t_symbol pointer name. Otherwise NULL. 01798 * 01799 */ 01800 t_symbol *jit_object_findregisteredbyptr(void *x) 01801 { 01802 t_symbol *s=NULL; 01803 t_symbol *name_space=NULL; 01804 object_findregisteredbyptr(&name_space,&s,x); 01805 if (name_space!=REGOB_NAMESPACE_JITTER) 01806 s = NULL; 01807 return s; 01808 } 01809 01810 /** 01811 * Attaches an object as a client of a named server object for notification. 01812 * 01813 * @ingroup objectmod 01814 * 01815 * @param s name of server object 01816 * @param x client object pointer 01817 * 01818 * @return If successful, server object pointer. Otherwise NULL. 01819 * 01820 */ 01821 void *jit_object_attach(t_symbol *s, void *x) 01822 { 01823 return object_attach(REGOB_NAMESPACE_JITTER,s,x); 01824 } 01825 01826 /** 01827 * Detaches a client object from a named server object. 01828 * 01829 * @ingroup objectmod 01830 * 01831 * @param s name of server object 01832 * @param x client object pointer 01833 * 01834 * @return t_jit_err error code 01835 * 01836 */ 01837 t_jit_err jit_object_detach(t_symbol *s, void *x) 01838 { 01839 t_max_err err; 01840 err = object_detach(REGOB_NAMESPACE_JITTER,s,x); 01841 return jit_err_from_max_err(err); 01842 } 01843 01844 /** 01845 * Notifies all client objects for a named server object. 01846 * 01847 * @ingroup objectmod 01848 * 01849 * @param x server object pointer 01850 * @param s notification message 01851 * @param data message specific data 01852 * 01853 * @return t_jit_err error code 01854 * 01855 */ 01856 t_jit_err jit_object_notify(void *x, t_symbol *s, void *data) 01857 { 01858 object_notify(x,s,data); 01859 return JIT_ERR_NONE; 01860 } 01861 01862 t_jit_err jit_object_shutdown(void) 01863 { 01864 if (_jit_object_init) { 01865 _jit_object_init=0; 01866 } 01867 return JIT_ERR_NONE; 01868 } 01869 01870 /** 01871 * Imports object attributes from an XML file. 01872 * 01873 * @ingroup objectmod 01874 * 01875 * @param x object pointer 01876 * @param s ignored 01877 * @param argc argument count 01878 * @param argv argument vector 01879 * 01880 * @return t_jit_err error code 01881 * 01882 */ 01883 t_jit_err jit_object_importattrs(void *x, t_symbol *s, long argc, t_atom *argv) 01884 { 01885 t_jit_linklist *attrlist; 01886 long size,i,j = 0; 01887 t_symbol *name; 01888 long err; 01889 long ac2,attrcount; 01890 t_atom *av2; 01891 t_jit_xml_document *doc; 01892 t_jit_xml_element *el; 01893 01894 // later establish some means of filtering which attributes are read? 01895 01896 if (doc=jit_xml_document_new(NULL,0,NULL)) { 01897 err = jit_xml_document_read(doc,s,argc,argv); 01898 if(err) 01899 { 01900 jit_object_error((t_object *)x,"jit_object_importattrs: error reading import file"); 01901 } 01902 01903 attrlist = jit_xml_document_getelementsbytagname(doc,gensym("attribute")); 01904 if(attrlist) 01905 { 01906 attrcount = jit_linklist_getsize(attrlist); 01907 for(i=0;i<attrcount;i++) 01908 { 01909 el = jit_linklist_getindex(attrlist,i); 01910 name = jit_xml_element_getattribute_sym(el, _jit_sym_name); 01911 ac2=0; av2=NULL; 01912 jit_xml_element_getattribute(el, gensym("value"),&ac2,&av2); 01913 // could enforce usercanset 01914 object_attr_setvalueof(x,name,ac2,av2); // always do for the empty value? 01915 if (ac2&&av2) { 01916 freebytes(av2,ac2*sizeof(t_atom)); 01917 } 01918 } 01919 jit_linklist_chuck(attrlist); 01920 } 01921 jit_object_free(doc); 01922 } 01923 return JIT_ERR_NONE; 01924 } 01925 01926 /** 01927 * Exports object attributes to an XML file. 01928 * 01929 * @ingroup objectmod 01930 * 01931 * @param x object pointer 01932 * @param s ignored 01933 * @param argc argument count 01934 * @param argv argument vector 01935 * 01936 * @return t_jit_err error code 01937 * 01938 */ 01939 t_jit_err jit_object_exportattrs(void *x, t_symbol *s, long argc, t_atom *argv) 01940 { 01941 t_jit_linklist *attrlist; 01942 long size,i,j = 0; 01943 t_symbol *name,*classname; 01944 t_jit_object *o; 01945 t_atom a[256]; 01946 char tmpstr[256]; 01947 long ac2; 01948 t_atom *av2; 01949 long symcount=0; 01950 t_symbol **symarray=NULL; 01951 t_jit_xml_document *doc; 01952 t_jit_xml_element *mel,*sel; 01953 01954 if (!x) 01955 return JIT_ERR_INVALID_PTR; 01956 01957 // later establish some means of filtering which attributes are written? 01958 01959 if (doc=jit_xml_document_new(NULL,0,NULL)) 01960 { 01961 if (mel=jit_xml_document_createelement(doc,gensym("c74object"))) 01962 { 01963 jit_xml_node_appendchild((t_jit_xml_node *)doc,(t_jit_xml_node *)mel); 01964 if (classname=jit_object_classname(x)) { 01965 for(i=0;classname->s_name[i];i++) 01966 tmpstr[i] = (classname->s_name[i]=='_') ? '.' : classname->s_name[i]; 01967 tmpstr[i] = 0; 01968 jit_atom_setsym(a,gensym(tmpstr)); 01969 jit_xml_element_setattribute(mel,gensym("class"),1,a); 01970 } 01971 if (x&&!object_attr_getnames(x,&symcount,&symarray)) 01972 { 01973 symbolarray_sort(symcount,symarray); 01974 for (i=0;i<symcount;i++) { 01975 if (o=object_attr_get(x,symarray[i])) { 01976 if (jit_object_method(o,gensym("usercanset"))&&jit_object_method(o,gensym("usercanget"))) 01977 { 01978 if (name = jit_object_method(o,_jit_sym_getname)) { 01979 if (sel=jit_xml_document_createelement(doc,gensym("attribute"))) { 01980 jit_atom_setsym(a,name); 01981 jit_xml_element_setattribute(sel,gensym("name"),1,a); 01982 ac2=0; av2=NULL; 01983 object_attr_getvalueof(x,name,&ac2,&av2); 01984 if (ac2&&av2) { 01985 jit_xml_element_setattribute(sel,gensym("value"),ac2,av2); 01986 freebytes(av2,ac2*sizeof(t_atom)); 01987 } 01988 jit_xml_node_appendchild((t_jit_xml_node *)mel,(t_jit_xml_node *)sel); 01989 } 01990 j++; 01991 } 01992 } 01993 } 01994 } 01995 } 01996 if (symarray) 01997 freebytes((char *)symarray,symcount*sizeof(t_symbol *)); 01998 } 01999 jit_xml_document_write(doc,NULL,argc,argv); 02000 jit_object_free(doc); 02001 } 02002 return JIT_ERR_NONE; 02003 } 02004 02005 /** 02006 * Exports object summary to an XML file. 02007 * 02008 * @warning Currently this function does nothing, but is reserved for future use. 02009 * 02010 * @ingroup objectmod 02011 * 02012 * @param x object pointer 02013 * @param s ignored 02014 * @param argc argument count 02015 * @param argv argument vector 02016 * 02017 * @return t_jit_err error code 02018 * 02019 */ 02020 t_jit_err jit_object_exportsummary(void *x, t_symbol *s, long argc, t_atom *argv) 02021 { 02022 return JIT_ERR_NONE; 02023 } 02024 02025 02026 #pragma mark - 02027 // -------------------------------------------------------------------------------- 02028 // error/posting stuff 02029 02030 #define POST_MAXCOLS 2048 02031 02032 char *post_class_stroffset(t_object *o, char *msg); 02033 char *post_class_stroffset(t_object *o, char *msg) 02034 { 02035 t_symbol *classname = object_classname(o); 02036 char *p; 02037 02038 if (classname&&classname!=_jit_sym_nothing) 02039 { 02040 p = strstr(msg,classname->s_name); 02041 if (p) { 02042 p += strlen(classname->s_name); 02043 if (p[0]&&p[0]==':') 02044 p++; 02045 if (p[0]&&p[0]==' ') 02046 p++; 02047 //post("eliminated classname string in (%s)", msg); 02048 return p; 02049 } 02050 } 02051 return msg; 02052 } 02053 02054 void jit_object_post(t_object *x, char *s, ...) 02055 { 02056 static t_symbol *ps_poundB=NULL; 02057 static t_symbol *ps_maxwrapper=NULL; 02058 char msg[POST_MAXCOLS+2]; 02059 char *msg2; 02060 t_object *box = NULL; 02061 t_object *wrapper = NULL; 02062 va_list ap; 02063 02064 if (!ps_poundB) { 02065 ps_poundB = gensym("#B"); 02066 ps_maxwrapper = gensym("maxwrapper"); 02067 } 02068 02069 va_start(ap,s); 02070 vsnprintf(msg, POST_MAXCOLS, s, ap); 02071 va_end(ap); 02072 msg[POST_MAXCOLS] = '\0'; 02073 02074 if (x&&(!NOGOOD(x))) { 02075 object_obex_lookup(x,ps_poundB,&box); 02076 if (box) { 02077 msg2 = post_class_stroffset(x,msg); 02078 object_post(x, msg2); 02079 return; 02080 } 02081 object_obex_lookup(x,ps_maxwrapper,&wrapper); 02082 if (wrapper) { 02083 msg2 = post_class_stroffset(wrapper,msg); 02084 object_post(wrapper, msg2); 02085 return; 02086 } 02087 } 02088 post(msg); 02089 } 02090 02091 void jit_object_error(t_object *x, char *s, ...) 02092 { 02093 static t_symbol *ps_poundB=NULL; 02094 static t_symbol *ps_maxwrapper=NULL; 02095 char msg[POST_MAXCOLS+2]; 02096 char *msg2; 02097 t_object *box = NULL; 02098 t_object *wrapper = NULL; 02099 va_list ap; 02100 02101 if (!ps_poundB) { 02102 ps_poundB = gensym("#B"); 02103 ps_maxwrapper = gensym("maxwrapper"); 02104 } 02105 02106 va_start(ap,s); 02107 vsnprintf(msg, POST_MAXCOLS, s, ap); 02108 va_end(ap); 02109 msg[POST_MAXCOLS] = '\0'; 02110 02111 if (x&&(!NOGOOD(x))) { 02112 object_obex_lookup(x,ps_poundB,&box); 02113 if (box) { 02114 msg2 = post_class_stroffset(x,msg); 02115 object_error(x, msg2); 02116 return; 02117 } 02118 object_obex_lookup(x,ps_maxwrapper,&wrapper); 02119 if (wrapper) { 02120 msg2 = post_class_stroffset(wrapper,msg); 02121 object_error(wrapper, msg2); 02122 return; 02123 } 02124 } 02125 error(msg); 02126 } 02127 02128 02129 02130 void jit_error_dosym(void *x,t_symbol *s); 02131 void jit_error_dosym(void *x,t_symbol *s) 02132 { 02133 jit_object_error((t_object *)x,"%s: %s",ob_sym(x)->s_name,s->s_name); 02134 } 02135 02136 /** 02137 * Sends symbol based error message to Max console (safe from all threads) 02138 * 02139 * @ingroup utilitymod 02140 * 02141 * @param x object pointer 02142 * @param s error message symbol 02143 * 02144 */ 02145 void jit_error_sym(void *x,t_symbol *s) 02146 { 02147 defer(x,(method)jit_error_dosym,s,0,0L); 02148 } 02149 02150 void jit_error_docode(void *x,t_jit_err v); 02151 void jit_error_docode(void *x,t_jit_err v) 02152 { 02153 switch (v) { 02154 case 0: 02155 case JIT_ERR_SUPPRESS_OUTPUT: 02156 break; 02157 case JIT_ERR_GENERIC: 02158 jit_object_error((t_object *)x,"%s: error type unspecified",ob_sym(x)->s_name); 02159 break; 02160 case JIT_ERR_INVALID_OBJECT: 02161 jit_object_error((t_object *)x,"%s: invalid object",ob_sym(x)->s_name); 02162 break; 02163 case JIT_ERR_OBJECT_BUSY: 02164 jit_object_error((t_object *)x,"%s: object busy",ob_sym(x)->s_name); 02165 break; 02166 case JIT_ERR_OUT_OF_MEM: 02167 jit_object_error((t_object *)x,"%s: out of memory",ob_sym(x)->s_name); 02168 break; 02169 case JIT_ERR_INVALID_PTR: 02170 jit_object_error((t_object *)x,"%s: invalid pointer",ob_sym(x)->s_name); 02171 break; 02172 case JIT_ERR_DUPLICATE: 02173 jit_object_error((t_object *)x,"%s: duplicate",ob_sym(x)->s_name); 02174 break; 02175 case JIT_ERR_OUT_OF_BOUNDS: 02176 jit_object_error((t_object *)x,"%s: out of bounds",ob_sym(x)->s_name); 02177 break; 02178 case JIT_ERR_INVALID_INPUT: 02179 jit_object_error((t_object *)x,"%s: invalid input",ob_sym(x)->s_name); 02180 break; 02181 case JIT_ERR_INVALID_OUTPUT: 02182 jit_object_error((t_object *)x,"%s: invalid output",ob_sym(x)->s_name); 02183 break; 02184 case JIT_ERR_MISMATCH_TYPE: 02185 jit_object_error((t_object *)x,"%s: mismatch type",ob_sym(x)->s_name); 02186 break; 02187 case JIT_ERR_MISMATCH_PLANE: 02188 jit_object_error((t_object *)x,"%s: mismatch plane",ob_sym(x)->s_name); 02189 break; 02190 case JIT_ERR_MISMATCH_DIM: 02191 jit_object_error((t_object *)x,"%s: mismatch dim",ob_sym(x)->s_name); 02192 break; 02193 case JIT_ERR_MATRIX_UNKNOWN: 02194 jit_object_error((t_object *)x,"%s: matrix unknown",ob_sym(x)->s_name); 02195 break; 02196 case JIT_ERR_DATA_UNAVAILABLE: 02197 jit_object_error((t_object *)x,"%s: data unavailable for request",ob_sym(x)->s_name); 02198 break; 02199 case JIT_ERR_HW_UNAVAILABLE: 02200 jit_object_error((t_object *)x,"%s: hardware unavailable for request",ob_sym(x)->s_name); 02201 break; 02202 default: 02203 jit_object_error((t_object *)x,"%s: '%c%c%c%c' (%d)",ob_sym(x)->s_name,((char *)v)[0],((char *)v)[1],((char *)v)[2],((char *)v)[3],(long)v); 02204 } 02205 } 02206 02207 /** 02208 * Sends error code based error message to Max console (safe from all threads) 02209 * 02210 * @ingroup utilitymod 02211 * 02212 * @param x object pointer 02213 * @param v error code 02214 * 02215 */ 02216 void jit_error_code(void *x,t_jit_err v) 02217 { 02218 defer(x,(method)jit_error_docode,(t_symbol *)v,0,0L); // hack: error number as symbol 02219 } 02220 02221 void jit_post_dosym(void *x,t_symbol *s); 02222 void jit_post_dosym(void *x,t_symbol *s) 02223 { 02224 jit_object_post((t_object *)x,"%s: %s",ob_sym(x)->s_name,s->s_name); 02225 } 02226 02227 /** 02228 * Sends symbol based message to Max console (safe from all threads) 02229 * 02230 * @ingroup utilitymod 02231 * 02232 * @param x object pointer 02233 * @param s message symbol 02234 * 02235 */ 02236 void jit_post_sym(void *x,t_symbol *s) 02237 { 02238 defer(x,(method)jit_post_dosym,s,0,0L); 02239 } 02240 02241 /** 02242 * Converts Max style error codes to Jitter style error codes 02243 * 02244 * @ingroup utilitymod 02245 * 02246 * @param err Max error code 02247 * 02248 * @return t_jit_err error code 02249 * 02250 */ 02251 t_jit_err jit_err_from_max_err(t_max_err err) 02252 { 02253 switch (err) { 02254 case MAX_ERR_NONE: 02255 return JIT_ERR_NONE; 02256 case MAX_ERR_GENERIC: 02257 return JIT_ERR_GENERIC; 02258 case MAX_ERR_INVALID_PTR: 02259 return JIT_ERR_INVALID_PTR; 02260 case MAX_ERR_DUPLICATE: 02261 return JIT_ERR_DUPLICATE; 02262 case MAX_ERR_OUT_OF_MEM: 02263 return JIT_ERR_OUT_OF_MEM; 02264 default: 02265 return JIT_ERR_GENERIC; 02266 } 02267 } 02268 02269 // taken from c74support-private/mac-support/CurrentBundle.c and modified for frameworks 02270 02271 #if TARGET_RT_MAC_MACHO 02272 02273 #include <dlfcn.h> 02274 02275 CFBundleRef GetCurrentlyExecutingFrameworkBundleOfFunction(void *fun); // declared below 02276 02277 short open_framework_resources(CFBundleRef *bun) 02278 { 02279 short rsRefNum; 02280 02281 *bun = GetCurrentlyExecutingFrameworkBundleOfFunction((void *)open_framework_resources); 02282 if (*bun) { 02283 rsRefNum = CFBundleOpenBundleResourceMap(*bun); 02284 if (rsRefNum != -1) 02285 return rsRefNum; 02286 else { 02287 CFRelease(*bun); 02288 *bun = 0; 02289 return -1; 02290 } 02291 } else 02292 return -1; 02293 } 02294 02295 void close_framework_resources(CFBundleRef bun, short ref) 02296 { 02297 if (bun && ref != -1) 02298 CFBundleCloseBundleResourceMap(bun,ref); 02299 if (bun) 02300 CFRelease(bun); 02301 } 02302 02303 CFBundleRef GetCurrentlyExecutingFrameworkBundleOfFunction(void *fun) 02304 { 02305 Dl_info info; 02306 CFURLRef url; 02307 CFBundleRef bun; 02308 char str[512]; 02309 char *p; 02310 02311 dladdr(fun,&info); // ask dynamic loader (10.3 or later) for address of something 02312 strcpy(str,info.dli_fname); 02313 p = strstr(str,"JitterAPI.framework"); 02314 if (p) { 02315 *(p+strlen("JitterAPI.framework")) = 0; 02316 } else 02317 return NULL; 02318 url = CFURLCreateFromFileSystemRepresentation (kCFAllocatorDefault,(UInt8 *)str, strlen(str),true); 02319 if (!url) 02320 return NULL; 02321 bun = CFBundleCreate(kCFAllocatorDefault,url); 02322 CFRelease(url); 02323 return bun; 02324 } 02325 02326 #endif
Copyright © 2008, Cycling '74