1 /*
2 TiMidity++ -- MIDI to WAVE converter and player
3 Copyright (C) 1999-2004 Masanao Izumo <iz@onicos.co.jp>
4 Copyright (C) 1995 Tuukka Toivonen <tt@cgs.fi>
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19
20 Macintosh interface for TiMidity
21 by T.Nogami <t-nogami@happy.email.ne.jp>
22
23 mac_c.c
24 Macintosh control mode
25 */
26
27 #ifdef HAVE_CONFIG_H
28 #include "config.h"
29 #endif /* HAVE_CONFIG_H */
30 #include <stdio.h>
31 #include <stdlib.h>
32 #include <string.h>
33 #include <stdarg.h>
34
35 #include <Drag.h>
36 #include <Icons.h>
37 #include <Threads.h>
38 #include <TextUtils.h>
39
40 #include "timidity.h"
41 #include "common.h"
42 #include "output.h"
43 #include "controls.h"
44 #include "instrum.h"
45 #include "playmidi.h"
46 #include "mfnode.h"
47 #include "miditrace.h"
48 #ifdef SUPPORT_SOUNDSPEC
49 #include "soundspec.h"
50 #endif /* SUPPORT_SOUNDSPEC */
51
52 #include "mac_main.h"
53 #include "mac_util.h"
54 #include "mac_c.h"
55 #ifdef MAC_USE_OMS
56 #include "mac_oms.h"
57 #endif
58
59 // *******************************
60
61 static void ctl_refresh(void);
62 static void ctl_total_time(int tt);
63 static void ctl_master_volume(int mv);
64 static void ctl_file_name(char *name);
65 static void ctl_current_time(int ct, int v);
66 static void ctl_note(int status, int ch, int note, int vel);
67 static void ctl_volume(int channel, int val);
68 static void ctl_expression(int channel, int val);
69 static void ctl_panning(int channel, int val);
70 static void ctl_sustain(int channel, int val);
71 static void ctl_pitch_bend(int channel, int val);
72 static void ctl_reset(void);
73 static int ctl_open(int using_stdin, int using_stdout);
74 static int ctl_pass_playing_list(int number_of_files, char *list_of_files[]);
75 static void ctl_close(void);
76 static int ctl_read(int32 *valp);
77 static int cmsg(int type, int verbosity_level, char *fmt, ...);
78 static void ctl_event(CtlEvent *e);
79
80 /**********************************/
81 /* export the interface functions */
82
83 #define ctl mac_control_mode
84
85 ControlMode ctl=
86 {
87 "mac interface", 'm',
88 "mac",
89 1,1,0,
90 0,
91 ctl_open,
92 ctl_close,
93 ctl_pass_playing_list,
94 ctl_read,
95 NULL,
96 cmsg,
97 ctl_event
98 };
99
100 static uint32 cuepoint = 0;
101 static int cuepoint_pending = 0;
102
103 // ***********************************************
104 Boolean gCursorIsWatch, gHasDragMgr;
105 #define FILESTR_LEN 40
106 #define TIMESTR_LEN 10
107 char fileStr[FILESTR_LEN]="", timeStr[TIMESTR_LEN]="";
108 Rect rFileName={10,10, 26,140},
109 rTime={10,150, 26,200},
110 rLogo={38,5,94,98},
111 rVol={28,220,92,239},
112
113 rPlay={40,110,62,142},
114 rStop={40,145,62,177},
115 rPause={40,180,62,212},
116 rPrevious={70,110,92,142},
117 rForward={70,145,92,177},
118 rEject={70,180,92,212},
119 rLoop={8,210,28,240};
120
121 PicHandle logo, logoDown;
122 //static RgnHandle receiveRgn;
123 CIconHandle button[6], iconPlay, iconPause, iconVol, iconTab, iconNotLoop,iconLoop;
124 static TEHandle gLogTE=0,gDocTE=0;
125
126 /****************************************/
127 static Boolean recieveHiliting;
128
DragTrackingProc(DragTrackingMessage theMessage,WindowPtr,void *,DragReference)129 pascal OSErr DragTrackingProc(
130 DragTrackingMessage theMessage,
131 WindowPtr /*window*/,
132 void* /*theRefCon*/,
133 DragReference /*drag*/)
134 {
135 switch (theMessage)
136 {
137 case kDragTrackingEnterWindow:
138 SetPort(mac_PlayerWindow.ref);
139 //ShowDragHilite(drag, receiveRgn, true);
140 DrawPicture(logoDown, &rLogo);
141 recieveHiliting=true;
142 break;
143 case kDragTrackingInWindow:
144 break;
145 case kDragTrackingLeaveWindow:
146 if( recieveHiliting )
147 {
148 SetPort(mac_PlayerWindow.ref);
149 //HideDragHilite(drag);
150 DrawPicture(logo, &rLogo);
151 recieveHiliting=false;
152 }
153 break;
154 }
155 return noErr;
156 }
157
DragReceiveFunc(WindowPtr,void *,DragReference drag)158 pascal OSErr DragReceiveFunc(
159 WindowPtr /*window*/,
160 void* /*theRefCon*/,
161 DragReference drag)
162 {
163 long i;
164 char* data;
165 unsigned short numFlavors;
166 Size dataSize;
167 ItemReference theItem;
168 unsigned short itemCount;
169 FlavorType flavor;
170
171 if( recieveHiliting )
172 {
173 int oldListEnd=mac_n_files;
174 CountDragItems(drag, &itemCount);
175
176 for( i=1; i<=itemCount; i++)
177 {
178 GetDragItemReferenceNumber(drag, i, &theItem);
179
180 if( noErr!=CountDragItemFlavors(drag, theItem, &numFlavors))
181 continue;
182 if( noErr!=GetFlavorType(drag, theItem, 1, &flavor))
183 continue;
184 if( noErr!=GetFlavorDataSize(drag, theItem, flavor, &dataSize))
185 continue;
186 data= (char*)malloc(dataSize);
187 if( data==0 ) continue;
188
189 if( noErr!=GetFlavorData(drag, theItem, flavor,
190 data, &dataSize, 0))
191 continue;
192 if(flavor== flavorTypeHFS)
193 AddHFS2PlayList((HFSFlavor*)data);
194 free(data);
195 }
196 if( gShuffle ) ShuffleList( oldListEnd, mac_n_files);
197 }
198
199 return noErr;
200 }
201
202 // *****************************************************
203 #pragma mark -
204
open_window(MacWindow * macwin,short resID)205 int open_window(MacWindow* macwin, short resID)
206 {
207 macwin->ref=GetNewCWindow(resID, 0, (WindowRef)-1);
208 if( macwin->ref==0) mac_ErrorExit("\pCannot open Window!");
209 SetWRefCon(macwin->ref, (long)macwin);
210 return 0;
211 }
212
position_window(MacWindow * macwin)213 void position_window(MacWindow* macwin)
214 {
215 Point p;
216
217 p.h=macwin->X; p.v=macwin->Y;
218 if( PtInRect(p, &qd.screenBits.bounds) ){
219 MoveWindow(macwin->ref, macwin->X, macwin->Y, true);
220 }
221 SizeWindow(macwin->ref, macwin->width, macwin->hight, 0);
222
223 if( macwin->show ) ShowWindow(macwin->ref);
224 }
225
setsize_window(MacWindow * macwin)226 static void setsize_window(MacWindow* macwin)
227 {
228 SizeWindow(macwin->ref, macwin->width, macwin->hight, 0);
229 }
230
goaway_default(MacWindow * macwin)231 void goaway_default(MacWindow* macwin)
232 {
233 HideWindow(macwin->ref); macwin->show=false;
234 }
235
close_default(MacWindow * macwin)236 void close_default(MacWindow* macwin)
237 {
238 Point p;
239 Rect r;
240
241 //Get Log Window position
242 SetPortWindowPort(macwin->ref);
243 p.v=p.h=0;
244 LocalToGlobal(&p);
245 macwin->X=p.h, macwin->Y=p.v;
246 r= GetWindowPort(macwin->ref)->portRect;
247 macwin->width= r.right-r.left;
248 macwin->hight= r.bottom-r.top;
249 }
250
251 // *****************************************************
252 #pragma mark -
253 #pragma mark =================Player Window
254
255 static int open_PlayerWin();
256 static void click_PlayerWin(Point local, short modifiers);
257 static void update_PlayerWin();
258 static void goaway_PlayerWin(MacWindow*);
259 static int message_PlayerWin(int message, long param);
260
261 #define win mac_PlayerWindow
262 MacWindow win={
263 0, //WindowRef
264 open_PlayerWin,
265 click_PlayerWin,
266 update_PlayerWin,
267 goaway_PlayerWin,
268 close_default,
269 message_PlayerWin,
270 1, 10,50
271 };
272
mac_setVolume(short amplitude)273 void mac_setVolume(short amplitude)
274 {
275 SndCommand theCmd;
276
277 if( amplitude<0 ) amplitude=0;
278 if( amplitude>255 ) amplitude=255;
279 theCmd.cmd=ampCmd;
280 theCmd.param1=amplitude;
281 SndDoImmediate(gSndCannel, &theCmd);
282 }
283
DoVolume()284 void DoVolume()
285 {
286 short lastAmp=mac_amplitude;
287 //SndCommand theCmd;
288 Point p;
289
290 SetPortWindowPort(win.ref);
291 GetMouse(&p);
292 /*GlobalToLocal(&p);*/
293 if( PtInRect(p, &rVol) && FrontWindow()==win.ref )
294 {
295
296 mac_amplitude=255*((double)rVol.bottom-10-p.v)/(rVol.bottom-rVol.top-20);
297 if( mac_amplitude<0 ) mac_amplitude=0;
298 if( mac_amplitude>255 ) mac_amplitude=255;
299
300 if( lastAmp!=mac_amplitude )
301 {
302 //theCmd.cmd=ampCmd;
303 //theCmd.param1=mac_amplitude;
304 //SndDoImmediate(gSndCannel, &theCmd);
305 mac_setVolume(mac_amplitude);
306 InvalRect(&rVol);
307 }
308 }
309 }
310
DrawButton()311 void DrawButton()
312 {
313 SetPortWindowPort(win.ref);
314 PlotCIcon(&rPlay, skin_state==PLAYING || skin_state==PAUSE? iconPlay:button[0] );
315 PlotCIcon(&rStop, button[1]);
316 PlotCIcon(&rPause, skin_state==PAUSE? iconPause:button[2] );
317 PlotCIcon(&rPrevious, button[3]);
318 PlotCIcon(&rForward, button[4]);
319 PlotCIcon(&rEject, button[5]);
320 }
321
DrawFileStr()322 static void DrawFileStr()
323 {
324 SetPortWindowPort(win.ref);
325 TETextBox(fileStr, strlen(fileStr), &rFileName, teCenter);
326 }
327
DrawTimeStr()328 static void DrawTimeStr()
329 {
330 SetPortWindowPort(win.ref);
331 TETextBox(timeStr, strlen(timeStr), &rTime, teCenter);
332 }
333
open_PlayerWin()334 static int open_PlayerWin()
335 /*success-> return 0;*/
336 {
337 int i;
338 OSErr err;
339 RGBColor back={0,0,0},
340 fore={65535,65535,65535};
341
342 open_window( &win, kPlayerWinID);
343 position_window(&win);
344
345 SetPortWindowPort(win.ref);
346 RGBForeColor(&fore);
347 RGBBackColor(&back);
348 logo= GetPicture(128);
349 logoDown= GetPicture(132);
350
351 for(i=0; i<6; i++)
352 button[i]= GetCIcon(i+200);
353 iconPlay=GetCIcon(210);
354 iconPause=GetCIcon(211);
355 iconVol=GetCIcon(206);
356 iconTab=GetCIcon(207);
357 iconNotLoop=GetCIcon(208);
358 iconLoop=GetCIcon(209);
359
360 if(gHasDragMgr)
361 {
362 //receiveRgn=NewRgn();
363 //if( receiveRgn )
364 {
365 //GetWindowContentRgn(win.ref, receiveRgn);
366 err=InstallTrackingHandler(NewDragTrackingHandlerProc(DragTrackingProc),
367 (WindowPtr)win.ref, 0);
368 if(err) ExitToShell();
369
370 err=InstallReceiveHandler(NewDragReceiveHandlerProc(DragReceiveFunc),
371 (WindowPtr)win.ref, 0);
372 if(err) ExitToShell();
373 }
374 }
375 return 0;
376 }
377
click_PlayerWin(Point p,short)378 static void click_PlayerWin(Point p, short /*modifiers*/)
379 {
380 if( PtInRect(p, &rStop)){ mac_rc=RC_QUIT; ctl_current_time(0,0); }
381 else if( PtInRect(p, &rPlay)){ mac_rc=RC_CONTINUE; }
382 else if( PtInRect(p, &rPause)){ mac_rc=RC_TOGGLE_PAUSE; }
383 else if( PtInRect(p, &rPrevious)){ mac_rc=RC_PREVIOUS; }
384 else if( PtInRect(p, &rForward)){ mac_rc=RC_NEXT; }
385 else if( PtInRect(p, &rEject)){
386 if( skin_state==PLAYING ) mac_rc=RC_QUIT;
387 skin_state=WAITING; mac_n_files=nPlaying=0; fileStr[0]=timeStr[0]=0;
388 init_ListWin();
389 update_PlayerWin();
390 }
391 else if( PtInRect(p, &rLoop)){ skin_f_repeat=!skin_f_repeat; SetPortWindowPort(win.ref);
392 InvalRect(&rLoop); return; } /* don't call mac_HandleControl();*/
393 else if( PtInRect(p, &rVol)) DoVolume();
394 else return; /* no button click*/
395
396 /* if button clicked */
397 mac_HandleControl();
398 }
399
update_PlayerWin()400 static void update_PlayerWin()
401 {
402 short y=((double)mac_amplitude/255)*(rVol.bottom-rVol.top-20);
403 Rect rFrame,rTab;
404
405 SetPortWindowPort(win.ref);
406 DrawButton();
407 skin_f_repeat? PlotCIcon(&rLoop, iconLoop):PlotCIcon(&rLoop, iconNotLoop);
408 PlotCIcon(&rVol, iconVol);
409 SetRect(&rTab, rVol.left+2, rVol.top+49-y, rVol.right-2, rVol.top+59-y);
410 PlotCIcon(&rTab, iconTab);
411
412 rFrame=rFileName; InsetRect(&rFrame, -2, -2); DrawPicture(GetPicture(129), &rFrame);
413 rFrame=rTime; InsetRect(&rFrame, -2, -2); DrawPicture(GetPicture(130), &rFrame);
414
415 DrawPicture(logo, &rLogo);
416
417 DrawTimeStr();
418 DrawFileStr();
419 }
420
goaway_PlayerWin(MacWindow * macwin)421 static void goaway_PlayerWin(MacWindow *macwin)
422 {
423 Do_Quit();
424 }
425
message_PlayerWin(int,long)426 static int message_PlayerWin(int /*message*/, long /*param*/)
427 {
428 return -1;
429 }
430
431 #undef win
432
433
434 // *****************************************************
435 #pragma mark -
436 #pragma mark ==================Log Window
437
438 static int open_LogWin();
439 static void click_LogWin(Point local, short modifiers);
440 static void update_LogWin();
441 static int message_LogWin(int message, long param);
442
443 #define win mac_LogWindow
444 MacWindow win={
445 0, //WindowRef
446 open_LogWin,
447 click_LogWin,
448 update_LogWin,
449 goaway_default,
450 close_default,
451 message_LogWin,
452 1, 270,60, 300,200
453 };
454
PrintLogStr(char str[])455 static void PrintLogStr(char str[])
456 {
457 int len=strlen(str);
458
459 if( !mac_LogWindow.show ) return;
460
461 if( (**gLogTE).teLength > 10000) /* clear first half*/
462 {
463 TEFeatureFlag(teFAutoScroll, teBitClear, gLogTE);
464 TESetSelect(0, 5000, gLogTE);
465 TEDelete(gLogTE);
466 }
467
468 TESetSelect((**gLogTE).teLength, (**gLogTE).teLength, gLogTE); /* move to end*/
469 if( len>=1 && str[len-1]=='\n' ){
470 str[len-1]=0; len--; //convert dos return code to mac's
471 }
472 TEInsert(str, len, gLogTE);
473 TESelView(gLogTE);
474 TEFeatureFlag(teFAutoScroll, teBitSet, gLogTE);
475 }
476
open_LogWin()477 static int open_LogWin()
478 /*success-> return 0;*/
479 {
480 open_window(&win, kLogWinID);
481 position_window(&win);
482 setsize_window(&win);
483
484 SetPortWindowPort(win.ref);
485 TextSize(10);
486 gLogTE=TENew(&win.ref->portRect, &win.ref->portRect);
487 if( gLogTE==0 ) mac_ErrorExit("\ppCannot open LogWindow!");
488
489 TEFeatureFlag(teFAutoScroll, teBitSet, gLogTE);
490 TEActivate(gLogTE);
491 return 0;
492 }
493
click_LogWin(Point local,short)494 static void click_LogWin(Point local, short /*modifiers*/)
495 {
496 TEClick(local, 0, gLogTE);
497 }
498
update_LogWin()499 static void update_LogWin()
500 {
501 SetPortWindowPort(win.ref);
502 TEUpdate(&win.ref->portRect, gLogTE);
503 }
504
message_LogWin(int message,long)505 static int message_LogWin(int message, long /*param*/)
506 {
507 Rect rect;
508
509 switch(message){
510 case MW_GROW:
511 rect=win.ref->portRect;
512 //rect.right-=15; rect.bottom-=15;
513 rect = win.ref->portRect;
514 rect.right -= 15;
515 //rect.bottom -= 15;
516 (**gLogTE).viewRect= (**gLogTE).destRect= rect;
517 (**gLogTE).destRect.right = (**gLogTE).destRect.right - 14;
518 TECalText(gLogTE);
519 TESetSelect((**gLogTE).teLength, (**gLogTE).teLength, gLogTE);
520 return 0;
521 }
522
523 return -1; //not supported
524 }
525
526 #undef win
527 // *****************************************************
528 #pragma mark -
529 #pragma mark ==================List Window
530
531 ListHandle gPlaylist;
532
533 static int open_ListWin();
534 static void click_ListWin(Point local, short modifiers);
535 static void update_ListWin();
536 static int message_ListWin(int message, long param);
537
538 enum{
539 MW_LIST_SELECT= 0x00010001,
540 MW_DOC_SET= 0x00020001
541 };
542
543 #define win mac_ListWindow
544 MacWindow win={
545 0, //WindowRef
546 open_ListWin,
547 click_ListWin,
548 update_ListWin,
549 goaway_default,
550 close_default,
551 message_ListWin,
552 1, 100,100, 300,200
553 };
554
change_ListRow(short row,const MidiFile * file)555 void change_ListRow( short row, const MidiFile* file)
556 {
557 Point aCell;
558 char buf[256]="",*p;
559
560 if( file && file->mfn && file->mfn->title )
561 {
562 strncpy(buf, file->mfn->title, sizeof(buf) - 1);
563 buf[sizeof(buf)-1] = '\0';
564 }
565
566 p= strrchr(file->filename, PATH_SEP);
567 if( p ){
568 size_t len = strlen(buf);
569 snprintf(&buf[len], sizeof(buf)-len-1, " (%s)", p+1);
570 buf[sizeof(buf)-1] = '\0';
571 }
572
573 SetPt(&aCell, 0, row);
574 LSetCell( buf, strlen(buf), aCell, gPlaylist);
575 }
576
add_ListWin(MidiFile * file)577 void add_ListWin(MidiFile * file)
578 {
579 short rowNum=1;
580 //Str255 fullPath;
581
582 //GetFullPath(&file->spec, fullPath);
583 file->mfn=make_new_MFnode_entry(file->filename);
584 rowNum = (**gPlaylist).dataBounds.bottom;
585 rowNum = LAddRow(1, rowNum, gPlaylist);
586 change_ListRow( rowNum, file);
587 }
588
init_ListWin()589 void init_ListWin()
590 {
591 short rowNum= (**gPlaylist).dataBounds.bottom;
592
593 SetPortWindowPort(win.ref);
594 LDelRow(0, 0, gPlaylist);
595 }
596
open_ListWin()597 static int open_ListWin()
598 /*success-> return 0;*/
599 {
600 Rect listRect, dataBounds;
601 Point cSize;
602
603 open_window(&win, kListWinID);
604 position_window(&win);
605 setsize_window(&win);
606
607 SetPortWindowPort(win.ref);
608 TextSize(10);
609 listRect=win.ref->portRect; listRect.right-=14; listRect.bottom-=14;
610 dataBounds.top=dataBounds.left=0; dataBounds.right=1; dataBounds.bottom=0;
611 cSize.h=1024; cSize.v=14;
612 gPlaylist = LNew(&listRect, &dataBounds, cSize, 0, win.ref,
613 1, 1, 0, 1);
614 return 0;
615 }
616
click_ListWin(Point local,short modifiers)617 static void click_ListWin(Point local, short modifiers)
618 {
619 Boolean doubleclick;
620 Cell cell;
621
622 SetPortWindowPort(win.ref);
623 doubleclick=LClick(local, modifiers, gPlaylist);
624 if(doubleclick){
625 mac_rc=RC_LOAD_FILE;
626 cell = LLastClick(gPlaylist);
627 nPlaying=cell.v;
628 mac_HandleControl();
629 }
630 }
631
update_ListWin()632 static void update_ListWin()
633 {
634 SetPortWindowPort(win.ref);
635 LUpdate( win.ref->visRgn, gPlaylist);
636 DrawGrowIcon(win.ref);
637 }
638
message_ListWin(int message,long param)639 static int message_ListWin(int message, long param)
640 {
641 Cell cell;
642 Rect rect;
643
644 switch(message){
645 case MW_GROW:
646 rect=win.ref->portRect;
647 LSize(rect.right-14, rect.bottom-14, gPlaylist);
648 return 0;
649
650 case MW_LIST_SELECT:
651 LDeselectAll(gPlaylist);
652 cell.h=0; cell.v=param;
653 LSetSelect(true, cell, gPlaylist);
654 LAutoScroll(gPlaylist);
655 return 0;
656 }
657
658 return -1; //not supported
659 }
660
661 #undef win
662 // *****************************************************
663 #pragma mark -
664 #pragma mark ==================Doc Window
665
666 static int open_DocWin();
667 static void click_DocWin(Point local, short modifiers);
668 static void update_DocWin();
669 static void close_DocWin();
670 static int message_DocWin(int message, long param);
671
672 #define win mac_DocWindow
673 MacWindow win={
674 0, //WindowRef
675 open_DocWin,
676 click_DocWin,
677 update_DocWin,
678 goaway_default,
679 close_default,
680 message_DocWin,
681 0, 150,150, 300,200
682 };
683
PrintDocStr(char str[])684 static void PrintDocStr(char str[])
685 {
686 if( (**gDocTE).teLength > 10000) /* clear first half*/
687 {
688 TESetSelect(0, 5000, gDocTE);
689 TEDelete(gDocTE);
690 }
691
692 TESetSelect((**gDocTE).teLength, (**gDocTE).teLength, gDocTE); /* move to end*/
693 TEInsert(str, strlen(str), gDocTE);
694 TESelView(gDocTE);
695 }
696
open_DocWin()697 static int open_DocWin()
698 /*success-> return 0;*/
699 {
700 Rect r;
701
702 open_window(&win, kDocWinID);
703 position_window(&win);
704 setsize_window(&win);
705
706 SetPortWindowPort(win.ref);
707 TextSize(10);
708 r=win.ref->portRect; r.right-=16;
709 gDocTE=TENew(&r, &r);
710 if( gDocTE==0 ) mac_ErrorExit("\pCannot open DocWindow!");
711
712 TEFeatureFlag(teFAutoScroll, teBitSet, gDocTE);
713 TEActivate(gDocTE);
714 return 0;
715 }
716
click_DocWin(Point local,short)717 static void click_DocWin(Point local, short /*modifiers*/)
718 {
719 TEClick(local, 0, gDocTE);
720 }
721
update_DocWin()722 static void update_DocWin()
723 {
724 SetPortWindowPort(win.ref);
725 DrawGrowIcon(win.ref);
726 TEUpdate(&win.ref->portRect, gDocTE);
727 }
728
message_DocWin(int message,long param)729 static int message_DocWin(int message, long param)
730 {
731 switch(message){
732 case MW_GROW:
733 {
734 Rect rect;
735 rect=win.ref->portRect;
736 //rect.right-=15; rect.bottom-=15;
737 rect = win.ref->portRect;
738 rect.right -= 16;
739 //rect.bottom -= 15;
740 (**gDocTE).viewRect= (**gDocTE).destRect= rect;
741 //(**gDocTE).destRect.right = (**gDocTE).destRect.right - 14;
742 TECalText(gDocTE);
743 TESetSelect((**gDocTE).teLength, (**gDocTE).teLength, gDocTE);
744 return 0;
745 }
746 case MW_DOC_SET:
747 {
748 const char *midiname=(char*)param;
749 char *p, docname[256];
750
751 //midiname= (char*)param;
752 strncpy(docname, midiname, sizeof docname - 1);
753 docname[sizeof docname - 1] = '\0';
754 if((p = strrchr(docname, '.')) == NULL){
755 return 0;
756 }
757 else if(p - docname >= sizeof docname - 4) {
758 return 0; /* cannot strcpy: that cause buffer overrun */
759 }
760 if('A' <= p[1] && p[1] <= 'Z') strcpy(p + 1, "DOC");
761 else strcpy(p + 1, "doc");
762
763 TEReadFile( docname, gDocTE );
764 break;
765 }
766 }
767
768 return -1; //not supported
769 }
770
771 #undef win
772 // *****************************************************
773 #pragma mark -
774 #pragma mark ================== spec Window
775
776 static int open_SpecWin();
777 static void click_SpecWin(Point local, short modifiers);
778 static void update_SpecWin();
779 static void goaway_SpecWin(MacWindow*);
780 static int message_SpecWin(int message, long param);
781
782 #define win mac_SpecWindow
783 MacWindow win={
784 0, //WindowRef
785 open_SpecWin,
786 click_SpecWin,
787 update_SpecWin,
788 goaway_SpecWin,
789 close_default,
790 message_SpecWin,
791 0, 100,100
792 };
793
open_SpecWin()794 static int open_SpecWin()
795 /*success-> return 0;*/
796 {
797 #ifdef SUPPORT_SOUNDSPEC
798 open_window(&win, kSpecWinID);
799 position_window(&win);
800
801 //always
802 //if( win.show ){ //Preference on
803 open_soundspec();
804 soundspec_update_wave(NULL, 0);
805 //}
806 #endif /* SUPPORT_SOUNDSPEC */
807 return 0;
808 }
809
click_SpecWin(Point,short)810 static void click_SpecWin(Point /*local*/, short /*modifiers*/)
811 {
812 }
813
update_SpecWin()814 static void update_SpecWin()
815 {
816 SetPortWindowPort(win.ref);
817 }
818
goaway_SpecWin(MacWindow * macwin)819 static void goaway_SpecWin(MacWindow *macwin)
820 {
821 goaway_default(macwin);
822 //close_soundspec();
823 }
824
message_SpecWin(int message,long)825 static int message_SpecWin(int message, long /*param*/)
826 {
827 Rect rect;
828
829 switch(message){
830 case MW_GROW:
831 rect=win.ref->portRect;
832 //rect.right-=15; rect.bottom-=15;
833 rect = win.ref->portRect;
834 rect.right -= 15;
835 //rect.bottom -= 15;
836 return 0;
837
838 }
839
840 return -1; //not supported
841 }
842
843 #undef win
844 // *****************************************************
845 #pragma mark -
846 static MacWindow* WindowList[]={
847 &mac_PlayerWindow,
848 &mac_LogWindow,
849 &mac_ListWindow,
850 &mac_WrdWindow,
851 &mac_DocWindow,
852 &mac_SpecWindow,
853 &mac_TraceWindow,
854 &mac_SkinWindow,
855 0
856 };
857
DoUpdate(WindowRef win_ref)858 void DoUpdate(WindowRef win_ref)
859 {
860 MacWindow* macwin;
861
862 macwin = (MacWindow*)GetWRefCon(win_ref);
863 if( macwin ) macwin->update();
864 }
865
mac_AdjustMenus(short modifiers)866 static void mac_AdjustMenus(short modifiers)
867 {
868 MenuHandle filenemu=GetMenu(mFile),
869 synthemu=GetMenu(mSynth);
870
871
872 //CheckItem(filenemu, iLogWindow & 0xFFFF, gShowMsg);
873 //CheckItem(filenemu, iListWindow & 0xFFFF, gShowList);
874 //CheckItem(filenemu, iWrdWindow & 0xFFFF, gShowWrd);
875 if( modifiers & optionKey ){
876 //EnableItem(filenemu, iSkinWindow);
877 EnableItem(synthemu, iQuickTime);
878 EnableItem(synthemu, iOMS);
879 }
880 }
881
HandleMouseDown(EventRecord * event)882 void HandleMouseDown(EventRecord *event)
883 {
884 short part;
885 WindowRef window;
886 MacWindow *macwin;
887 Rect growRect={100,100,32000,32000};
888 long size;
889
890 part=FindWindow(event->where, &window);
891 macwin = (MacWindow*)GetWRefCon(window);
892
893 switch(part)
894 {
895 case inMenuBar:
896 mac_AdjustMenus(event->modifiers);
897 mac_HandleMenuSelect(MenuSelect(event->where), event->modifiers);
898 HiliteMenu(0);
899 break;
900 case inContent:
901 SetPortWindowPort(window);
902 SelectWindow(window);
903 GlobalToLocal(&event->where);
904 if(macwin) macwin->click(event->where, event->modifiers);
905 break;
906 case inDrag:
907 DragWindow(window, event->where, &qd.screenBits.bounds);
908 break;
909 case inGrow:
910 SetPortWindowPort(window);
911 size=GrowWindow(window, event->where, &growRect);
912 if( size )
913 {
914 SizeWindow(window, size&0x0000FFFF, size>>16, 0);
915 EraseRect(&GetWindowPort(window)->portRect);
916 InvalRect(&GetWindowPort(window)->portRect);
917 if( macwin ) macwin->message(MW_GROW, size);
918 }
919 break;
920 case inGoAway:
921 if( TrackGoAway(window, event->where) ){
922 if( macwin ){
923 macwin->goaway(macwin);
924 }
925 }
926 break;
927 //case inZoomIn:
928 //case inZoomOut:
929 // break;
930 }
931 }
932
933 // *****************************************************
934 #pragma mark -
935 #pragma mark ===============control function
936
937
ctl_open(int,int)938 static int ctl_open(int /*using_stdin*/, int /*using_stdout*/)
939 /*success-> return 0;*/
940 {
941 int i, err;
942
943 for(i=0; WindowList[i]; i++){
944 err=WindowList[i]->open();
945 if(err) break;
946 }
947 if( !err ) ctl.opened=1;
948 return err;
949 }
950
ctl_close(void)951 static void ctl_close(void)
952 {
953 int i;
954 for( i=0; WindowList[i]; i++ ){
955 WindowList[i]->close(WindowList[i]);
956 }
957
958 ctl.opened=0;
959 return;
960 }
961
962
ctl_pass_playing_list(int init_number_of_files,char * [])963 static int ctl_pass_playing_list(int init_number_of_files,
964 char * /*init_list_of_files*/ [])
965 {
966 EventRecord event;
967
968 if( init_number_of_files!=0 ){
969 cmsg(CMSG_FATAL, VERB_NORMAL,
970 "ctl_pass_playing_list: Sorry. Fatal error.");
971 }
972
973 #ifdef MAC_USE_OMS
974 mac_oms_setup();
975 #endif
976
977 {
978 FSSpec spec;
979 OSErr err;
980 err=FSMakeFSSpec(0, 0, MAC_STARTUP_FOLDER_NAME, &spec);
981 if( err==noErr ){ mac_add_fsspec( &spec ); }
982 }
983
984 gQuit=false;
985 while(!gQuit)
986 {
987 WaitNextEvent(everyEvent, &event, 1,0);
988 mac_HandleEvent(&event);
989 }
990 Do_Quit();
991 return 0;
992 }
993
UserWantsControl()994 static Boolean UserWantsControl()
995 {
996 /* Mouse down��or key down��*/
997 KeyMap km;
998
999 GetKeys(km);
1000 km[1] &= ~0x02; /* exclude caps lock */
1001 return Button() || km[0]|| km[1] || km[2] || km[3] || skin_state==PAUSE;
1002 }
1003
ctl_read(int32 *)1004 static int ctl_read(int32* /*valp*/)
1005 {
1006 int ret;
1007
1008 if (cuepoint_pending) {
1009 *valp = cuepoint;
1010 cuepoint_pending = 0;
1011 return RC_FORWARD;
1012 }
1013
1014 //if( gCursorIsWatch ){ gCursorIsWatch=false; InitCursor(); }
1015 if( gQuit ) Do_Quit(); /* Quit Apple event occured */
1016 if( mac_rc ){ret=mac_rc; mac_rc=0; return ret;}
1017 if( !gBusy || UserWantsControl()){
1018 YieldToAnyThread();
1019 }
1020 return RC_NONE;
1021 }
1022
ctl_lyric(int lyricid)1023 static void ctl_lyric(int lyricid)
1024 {
1025 char *lyric;
1026
1027 lyric = event2string(lyricid);
1028 if(lyric == NULL) return;
1029 ctl.cmsg(CMSG_TEXT, VERB_VERBOSE, "%s", lyric + 1);
1030 }
1031
ctl_gslcd(int lyricid)1032 static void ctl_gslcd(int lyricid)
1033 {
1034 char *lyric;
1035
1036 lyric = event2string(lyricid);
1037 if(lyric == NULL) return;
1038
1039 if( lyric[0] == ME_GSLCD ){
1040 int i,j, data, mask;
1041 char tmp[3]= "00";
1042
1043 lyric++;
1044 for( j=0; j<4; j++ ){
1045 for( i=0; i<16; i++ ){
1046 tmp[0]= lyric[0]; tmp[1]= lyric[1]; lyric+=2;
1047 sscanf(tmp, "%X", &data);
1048 mask=0x10;
1049 ctl_note((data&mask)? VOICE_ON:-1, i, 40+j*10, 127);
1050 ctl_note((data&mask)? VOICE_ON:-1, i, 41+j*10, 127); mask>>=1;
1051 ctl_note((data&mask)? VOICE_ON:-1, i, 42+j*10, 127);
1052 ctl_note((data&mask)? VOICE_ON:-1, i, 43+j*10, 127); mask>>=1;
1053 ctl_note((data&mask)? VOICE_ON:-1, i, 44+j*10, 127);
1054 ctl_note((data&mask)? VOICE_ON:-1, i, 45+j*10, 127); mask>>=1;
1055 ctl_note((data&mask)? VOICE_ON:-1, i, 46+j*10, 127);
1056 ctl_note((data&mask)? VOICE_ON:-1, i, 47+j*10, 127); mask>>=1;
1057 ctl_note((data&mask)? VOICE_ON:-1, i, 48+j*10, 127);
1058 ctl_note((data&mask)? VOICE_ON:-1, i, 49+j*10, 127); mask>>=1;
1059 }
1060 }
1061 return;
1062 }
1063 //else normal text
1064 ctl.cmsg(CMSG_TEXT, VERB_VERBOSE, "%s", lyric + 1);
1065 }
1066
cmsg(int type,int verbosity_level,char * fmt,...)1067 static int cmsg(int type, int verbosity_level, char * fmt, ...)
1068 {
1069 #define BUFSIZE 1024
1070 char buf[BUFSIZE];
1071 va_list ap;
1072
1073 if ((type==CMSG_TEXT || type==CMSG_INFO || type==CMSG_WARNING) &&
1074 ctl.verbosity<verbosity_level){
1075 return 0;
1076 }
1077 va_start(ap, fmt);
1078 {
1079 vsnprintf(buf, BUFSIZE, fmt, ap);
1080 if(mac_LogWindow.ref ){
1081 PrintLogStr(buf);
1082 PrintLogStr("\r");
1083 }
1084 if( !mac_LogWindow.ref || type==CMSG_FATAL){
1085 StopAlertMessage(c2pstr(buf)); /* no Window or Fatal ERR*/
1086 }
1087 }
1088 va_end(ap);
1089 return 0;
1090 }
1091
ctl_refresh(void)1092 static void ctl_refresh(void)
1093 {}
1094
ctl_total_time(int tt)1095 static void ctl_total_time(int tt)
1096 {
1097 mac_trc_update_time( -1, tt/play_mode->rate);
1098 mac_SkinWindow.message(MW_SKIN_TOTAL_TIME, tt/play_mode->rate);
1099 }
1100
ctl_master_volume(int)1101 static void ctl_master_volume(int /*mv*/) {}
1102
ctl_file_name(char * name)1103 static void ctl_file_name(char *name)
1104 {
1105 int i;
1106 char *s;
1107
1108 for( i=strlen(name); i>=0; i--)
1109 if( name[i]==PATH_SEP ) {
1110 s=&name[i]+1; //remove pathname
1111 break;
1112 }
1113 snprintf(fileStr, FILESTR_LEN, "%d. %s", nPlaying+1, s);
1114
1115 if (ctl.verbosity>=0 || ctl.trace_playing){
1116 DrawFileStr();
1117 }
1118 mac_ListWindow.message(MW_LIST_SELECT, nPlaying);
1119 mac_DocWindow.message(MW_DOC_SET, (long)name);
1120 mac_trc_update_all_info();
1121 mac_SkinWindow.message(MW_SKIN_FILENAME, (long)fileStr);
1122 }
1123
ctl_current_time(int current,int)1124 static void ctl_current_time(int current, int /*v*/)
1125 {
1126 static int lastSec=-1, lastYieldThread=-1;
1127 int mins, secs, realSecs;
1128
1129 if( gStartTick==0 ) gStartTick=TickCount();
1130 /*select*/
1131 realSecs=(TickCount()-gStartTick)/60; /*real time*/
1132 secs=current;
1133
1134 if( secs!=lastSec && (skin_state==PLAYING || skin_state==PAUSE))
1135 {
1136 lastSec=secs;
1137 mins=secs/60;
1138 secs-=mins*60;
1139 snprintf(timeStr, TIMESTR_LEN, "%02d:%02d", mins, secs);
1140 DrawTimeStr();
1141 mac_trc_update_time(current,-1);
1142 mac_SkinWindow.message(MW_SKIN_TIME, lastSec);
1143 }
1144 if( realSecs!=lastYieldThread ){
1145 lastYieldThread= realSecs;
1146 mac_trc_update_time(current,-1);
1147 mac_trc_update_voices();
1148 if( (realSecs % (evil_level*evil_level))==0 )
1149 YieldToAnyThread(); // YieldToAnyThread every 1sec
1150 }
1151 }
1152
ctl_note(int status,int ch,int note,int vel)1153 static void ctl_note(int status, int ch, int note, int vel)
1154 {
1155 if( ! mac_TraceWindow.show ) return;
1156 if(note == -1)
1157 {
1158 //if(ctl.trace_playing && !midi_trace.flush_flag)
1159 // push_midi_trace0(update_indicator);
1160 return;
1161 }
1162 //push_midi_note(v_ctl_note, note);
1163 v_ctl_note( status, ch, note, vel);
1164 }
1165
ctl_program(int ch,int val,char * comm)1166 static void ctl_program(int ch, int val, char *comm){mac_ctl_program(ch,val,comm);}
1167
ctl_volume(int,int)1168 static void ctl_volume(int /*channel*/, int /*val*/) {}
1169
ctl_expression(int,int)1170 static void ctl_expression(int /*channel*/, int /*val*/) {}
1171
ctl_panning(int,int)1172 static void ctl_panning(int /*channel*/, int /*val*/) {}
1173
ctl_sustain(int,int)1174 static void ctl_sustain(int /*channel*/, int /*val*/) {}
1175
ctl_pitch_bend(int,int)1176 static void ctl_pitch_bend(int /*channel*/, int /*val*/) {}
1177
ctl_reset(void)1178 static void ctl_reset(void)
1179 {
1180 mac_ctl_reset_trc();
1181 }
1182
ctl_event(CtlEvent * e)1183 static void ctl_event(CtlEvent *e)
1184 {
1185 switch(e->type)
1186 {
1187 case CTLE_NOW_LOADING:
1188 ctl_file_name((char *)e->v1);
1189 break;
1190 case CTLE_LOADING_DONE:
1191 break;
1192 case CTLE_PLAY_START:
1193 ctl_total_time((int)e->v1);
1194 break;
1195 case CTLE_PLAY_END:
1196 break;
1197 case CTLE_CUEPOINT:
1198 cuepoint = e->v1;
1199 cuepoint_pending = 1;
1200 break;
1201 case CTLE_TEMPO:
1202 break;
1203 case CTLE_METRONOME:
1204 break;
1205 case CTLE_CURRENT_TIME:
1206 ctl_current_time((int)e->v1, (int)e->v2);
1207 break;
1208 case CTLE_NOTE:
1209 ctl_note((int)e->v1, (int)e->v2, (int)e->v3, (int)e->v4);
1210 break;
1211 case CTLE_MASTER_VOLUME:
1212 ctl_master_volume((int)e->v1);
1213 break;
1214 case CTLE_PROGRAM:
1215 ctl_program((int)e->v1, (int)e->v2, (char *)e->v3);
1216 break;
1217 case CTLE_VOLUME:
1218 ctl_volume((int)e->v1, (int)e->v2);
1219 break;
1220 case CTLE_EXPRESSION:
1221 ctl_expression((int)e->v1, (int)e->v2);
1222 break;
1223 case CTLE_PANNING:
1224 ctl_panning((int)e->v1, (int)e->v2);
1225 break;
1226 case CTLE_SUSTAIN:
1227 ctl_sustain((int)e->v1, (int)e->v2);
1228 break;
1229 case CTLE_PITCH_BEND:
1230 ctl_pitch_bend((int)e->v1, (int)e->v2);
1231 break;
1232 case CTLE_MOD_WHEEL:
1233 ctl_pitch_bend((int)e->v1, e->v2 ? -1 : 0x2000);
1234 break;
1235 case CTLE_CHORUS_EFFECT:
1236 break;
1237 case CTLE_REVERB_EFFECT:
1238 break;
1239 case CTLE_LYRIC:
1240 ctl_lyric((int)e->v1);
1241 break;
1242 case CTLE_GSLCD:
1243 ctl_gslcd((int)e->v1);
1244 break;
1245 case CTLE_REFRESH:
1246 ctl_refresh();
1247 break;
1248 case CTLE_RESET:
1249 ctl_reset();
1250 break;
1251 #ifdef SUPPORT_SOUNDSPEC
1252 case CTLE_SPEANA:
1253 ctl_speana_data((double *)e->v1, (int)e->v2);
1254 break;
1255 #endif /* SUPPORT_SOUNDSPEC */
1256 }
1257 }
1258
1259