1 /*
2 TiMidity++ -- MIDI to WAVE converter and player
3 Copyright (C) 1999-2002 Masanao Izumo <mo@goice.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 motif_interface.c: written by Vincent Pagel (pagel@loria.fr) 10/4/95
21
22 Policy : I choose to make a separate process for a TIMIDITY motif
23 interface for TIMIDITY (if the interface was in the same process
24 X redrawings would interfere with the audio computation. Besides
25 XtAppAddWorkProc mechanism is not easily controlable)
26
27 The solution : I create a pipe between Timidity and the forked interface
28 and use XtAppAddInput to watch the data arriving on the pipe.
29
30 10/4/95
31 - Initial working version with prev, next, and quit button and a
32 text display
33
34 17/5/95
35 - Add timidity icon with filename displaying to play midi while
36 I work without having that big blue window in the corner of
37 my screen :)
38 - Solve the problem of concurent scale value modification
39
40 21/5/95
41 - Add menus, file selection box
42
43 14/6/95
44 - Make the visible part of file list follow the selection
45
46 */
47
48 #ifdef HAVE_CONFIG_H
49 #include "config.h"
50 #endif /* HAVE_CONFIG_H */
51 #include <stdio.h>
52 #include <stdlib.h>
53 #include <unistd.h>
54 #include <stdarg.h>
55
56 #include <Xm/Xm.h>
57 #include <Xm/Form.h>
58 #include <Xm/Text.h>
59 #include <Xm/PushB.h>
60 #include <Xm/Label.h>
61 #include <Xm/Scale.h>
62 #include <Xm/List.h>
63 #include <Xm/Frame.h>
64 #include <Xm/RowColumn.h>
65 #include <Xm/CascadeB.h>
66 #include <Xm/FileSB.h>
67 #include <Xm/FileSB.h>
68 #include <Xm/ToggleB.h>
69
70 #include "timidity.h"
71 #include "common.h"
72 #include "instrum.h"
73 #include "playmidi.h"
74 #include "output.h"
75 #include "controls.h"
76 #include "motif.h"
77
78 static XtAppContext context;
79 static XmStringCharSet char_set=XmSTRING_DEFAULT_CHARSET;
80
81 static Widget toplevel;
82
83 static Widget text;
84 static XmTextPosition wpr_position=0;
85
86 static Widget mainForm;
87
88 static Widget menu_bar, open_option, quit_option, auto_next_option;
89 static Widget open_dialog , add_all_button;
90
91 static Widget btnForm, backBtn,fwdBtn, restartBtn, pauseBtn, quitBtn,
92 nextBtn, prevBtn;
93
94 static Pixmap backPixmap, fwdPixmap, pausePixmap , restartPixmap,
95 prevPixmap, nextPixmap, quitPixmap,
96 timidityPixmap;
97
98 static Widget countFrame, countForm, counterlbl, totlbl , count_headlbl;
99 static int last_sec=0;
100 static int max_sec=0;
101
102 static Widget file_namelbl, file_headlbl;
103
104 static Widget volume_scale , locator_scale ;
105 static Boolean locator_scale_button= ButtonRelease;
106
107 static Widget file_list;
108 static int file_number_to_play; /* Number of the file we're playing in the list */
109
110 /*
111 * CREATE PIXMAPS FOR THE BUTONS
112 */
CreatePixmaps(Widget parent)113 static void CreatePixmaps(Widget parent)
114 {
115 /*
116 *
117 * BITMAPS
118 */
119 #include "motif_bitmaps/back.xbm"
120 #include "motif_bitmaps/next.xbm"
121 #include "motif_bitmaps/prev.xbm"
122 #include "motif_bitmaps/restart.xbm"
123 #include "motif_bitmaps/fwd.xbm"
124 #include "motif_bitmaps/pause.xbm"
125 #include "motif_bitmaps/quit.xbm"
126 #include "motif_bitmaps/timidity.xbm"
127
128 Display *disp;
129 Drawable d;
130 Pixel fg,bg;
131 int ac;
132 Arg al[20];
133 unsigned int depth=DefaultDepthOfScreen(XtScreen(toplevel));
134
135 ac = 0;
136 XtSetArg(al[ac], XmNbackground, &bg); ac++;
137 XtSetArg(al[ac], XmNforeground, &fg); ac++;
138 XtGetValues(parent, al, ac);
139
140 disp=XtDisplay(toplevel);
141 d=RootWindowOfScreen(XtScreen(toplevel));
142
143 backPixmap = XCreatePixmapFromBitmapData(disp, d,
144 back_bits, back_width, back_height,
145 fg, bg,depth);
146 fwdPixmap = XCreatePixmapFromBitmapData( disp, d,
147 fwd_bits, fwd_width, fwd_height,
148 fg, bg,depth);
149 pausePixmap = XCreatePixmapFromBitmapData(disp, d,
150 pause_bits, pause_width, pause_height,
151 fg, bg,depth);
152
153 restartPixmap = XCreatePixmapFromBitmapData(disp, d,
154 restart_bits, restart_width, restart_height,
155 fg, bg,depth);
156
157 nextPixmap = XCreatePixmapFromBitmapData(disp, d,
158 next_bits, next_width, next_height,
159 fg, bg,depth);
160
161 prevPixmap = XCreatePixmapFromBitmapData(disp, d,
162 prev_bits, prev_width, prev_height,
163 fg, bg,depth);
164
165 quitPixmap = XCreatePixmapFromBitmapData(disp, d,
166 quit_bits, quit_width, quit_height,
167 fg, bg,depth);
168
169 timidityPixmap = XCreatePixmapFromBitmapData(disp, d,
170 timidity_bits, timidity_width, timidity_height,
171 WhitePixelOfScreen(XtScreen(toplevel)),
172 BlackPixelOfScreen(XtScreen(toplevel)),depth);
173 }
174
175
176 /************************************
177 * *
178 * ALL THE INTERFACE'S CALLBACKS *
179 * *
180 ************************************/
181
182 /*
183 * Generic buttons callbacks ( Transport Buttons )
184 */
185 /*ARGSUSED*/
GenericCB(Widget widget,int data,XtPointer call_data)186 static void GenericCB(Widget widget, int data, XtPointer call_data)
187 {
188
189 if(data != MOTIF_QUIT && data != MOTIF_NEXT && data != MOTIF_PREV)
190 {
191 Arg al[10];
192 int ac, nbfile;
193
194 ac=0;
195 XtSetArg(al[ac], XmNitemCount, &nbfile); ac++;
196 XtGetValues(file_list, al, ac);
197 if(file_number_to_play==0||file_number_to_play>nbfile)
198 return;
199 }
200 m_pipe_int_write( data );
201 }
202
203 /*
204 * Generic scales callbacks : VOLUME and LOCATOR
205 */
206 /*ARGSUSED*/
Generic_scaleCB(Widget widget,int data,XtPointer call_data)207 static void Generic_scaleCB(Widget widget, int data, XtPointer call_data)
208 {
209 XmScaleCallbackStruct *cbs = (XmScaleCallbackStruct *) call_data;
210
211 if(data == MOTIF_CHANGE_LOCATOR)
212 {
213 Arg al[10];
214 int ac, nbfile;
215
216 ac=0;
217 XtSetArg(al[ac], XmNitemCount, &nbfile); ac++;
218 XtGetValues(file_list, al, ac);
219 if(file_number_to_play<=0||file_number_to_play>nbfile)
220 {
221 XmScaleSetValue(locator_scale,0);
222 return;
223 }
224 }
225 m_pipe_int_write( data );
226 m_pipe_int_write(cbs->value);
227 }
228
229 /*
230 * Detect when a mouse button is pushed or released in a scale area to
231 * avoid concurent scale value modification while holding it with the mouse
232 */
233 /*ARGSUSED*/
Locator_btn(Widget w,XtPointer client_data,XEvent * event,Boolean * cont)234 static void Locator_btn(Widget w,XtPointer client_data,XEvent *event,Boolean *cont)
235 {
236 /* Type = ButtonPress or ButtonRelease */
237 locator_scale_button= event->xbutton.type;
238 }
239
240 /*
241 * File List selection CALLBACK
242 */
243 /*ARGSUSED*/
File_ListCB(Widget widget,int data,XtPointer call_data)244 static void File_ListCB(Widget widget, int data, XtPointer call_data)
245 {
246 XmListCallbackStruct *cbs= (XmListCallbackStruct *) call_data;
247 char *text;
248 int nbvisible, first_visible ;
249 Arg al[10];
250 int ac;
251
252 /* First, check that the selected file is really visible in the list */
253 ac=0;
254 XtSetArg(al[ac],XmNtopItemPosition,&first_visible); ac++;
255 XtSetArg(al[ac],XmNvisibleItemCount,&nbvisible); ac++;
256 XtGetValues(widget, al, ac);
257
258 if ( ( first_visible > cbs->item_position) ||
259 ((first_visible+nbvisible) <= cbs->item_position))
260 XmListSetPos(widget, cbs->item_position);
261
262 /* Tell the application to play the requested file */
263 XmStringGetLtoR(cbs->item,char_set,&text);
264 m_pipe_int_write(MOTIF_PLAY_FILE);
265 m_pipe_string_write(text);
266 file_number_to_play=cbs->item_position;
267 XtFree(text);
268 }
269
270 /*
271 * Generic menu callback
272 */
273 /*ARGSUSED*/
menuCB(Widget w,int client_data,XmAnyCallbackStruct * call_data)274 static void menuCB(Widget w,int client_data,XmAnyCallbackStruct *call_data)
275 {
276 switch (client_data)
277 {
278 case MENU_OPEN:
279 {
280 XtManageChild(open_dialog);
281 }
282 break;
283
284 case MENU_QUIT : {
285 m_pipe_int_write(MOTIF_QUIT);
286 }
287 break;
288 case MENU_TOGGLE : {
289 /* Toggle modified : for the moment , nothing to do ! */
290 /* if (XmToggleButtonGetState(w)) TRUE else FALSE */
291 }
292 break;
293 }
294 }
295
296 /*
297 * File selection box callback
298 */
299 /*ARGSUSED*/
openCB(Widget w,int client_data,XmFileSelectionBoxCallbackStruct * call_data)300 static void openCB(Widget w,int client_data,XmFileSelectionBoxCallbackStruct *call_data)
301 {
302 if (client_data==DIALOG_CANCEL)
303 { /* do nothing if cancel is selected. */
304 XtUnmanageChild(open_dialog);
305 return;
306 }
307 else if (client_data==DIALOG_ALL)
308 { /* Add all the listed files */
309 Arg al[10];
310 int ac;
311 Widget the_list;
312 int nbfile;
313 XmStringTable files;
314 char *text;
315 int i;
316
317 the_list=XmFileSelectionBoxGetChild(open_dialog,XmDIALOG_LIST);
318 if (!XmIsList(the_list))
319 {
320 fprintf(stderr, "PANIC: List are not what they used to be"
321 NLS);
322 exit(1);
323 }
324
325 ac=0;
326 XtSetArg(al[ac], XmNitemCount, &nbfile); ac++;
327 XtSetArg(al[ac], XmNitems, &files); ac++;
328 XtGetValues(the_list, al, ac);
329
330 m_pipe_int_write(MOTIF_EXPAND);
331 m_pipe_int_write(nbfile);
332 for (i=0;i<nbfile;i++)
333 {
334 XmStringGetLtoR(files[i],char_set,&text);
335 m_pipe_string_write(text);
336 XtFree(text);
337 }
338 XtUnmanageChild(open_dialog);
339 }
340 else
341 { /* get filename from file selection box and add it to the list*/
342 char *text;
343
344 m_pipe_int_write(MOTIF_EXPAND);
345 m_pipe_int_write(1);
346 XmStringGetLtoR(call_data->value,char_set,&text);
347 m_pipe_string_write(text);
348 XtFree(text);
349 XtUnmanageChild(open_dialog);
350 }
351 }
352
353
354 /********************************************************
355 * *
356 * Receive DATA sent by the application on the pipe *
357 * *
358 ********************************************************/
359 /*ARGSUSED*/
handle_input(client_data,source,id)360 static void handle_input(client_data, source, id)
361 XtPointer client_data;
362 int *source;
363 XtInputId *id;
364 {
365 int message;
366
367 m_pipe_int_read(&message);
368
369 switch (message)
370 {
371 case REFRESH_MESSAGE : {
372 fprintf(stderr, "REFRESH MESSAGE IS OBSOLETE !!!" NLS);
373 }
374 break;
375
376 case TOTALTIME_MESSAGE : {
377 int tseconds;
378 int minutes,seconds;
379 char local_string[20];
380 Arg al[10];
381 int ac;
382
383 m_pipe_int_read(&tseconds);
384
385 seconds=tseconds;
386 minutes=seconds/60;
387 seconds-=minutes*60;
388 sprintf(local_string,"/ %02d:%02d",minutes,seconds);
389 ac=0;
390 XtSetArg(al[ac], XmNlabelString,
391 XmStringCreate(local_string, char_set)); ac++;
392 XtSetValues(totlbl, al, ac);
393
394 /* Readjust the time scale */
395 XmScaleSetValue(locator_scale,0);
396 ac=0;
397 XtSetArg(al[ac], XmNmaximum, tseconds); ac++;
398 XtSetValues(locator_scale, al, ac);
399 max_sec=tseconds;
400 }
401 break;
402
403 case MASTERVOL_MESSAGE: {
404 int volume;
405
406 m_pipe_int_read(&volume);
407 XmScaleSetValue(volume_scale,volume);
408 }
409 break;
410
411 case FILENAME_MESSAGE : {
412 char filename[255], separator[255];
413 Arg al[10];
414 char *pc;
415 int ac, i;
416 short nbcol;
417
418 m_pipe_string_read(filename);
419
420 /* Extract basename of the file */
421 pc=strrchr(filename,'/');
422 if (pc==NULL)
423 pc=filename;
424 else
425 pc++;
426
427 ac=0;
428 XtSetArg(al[ac], XmNlabelString,
429 XmStringCreate(pc, char_set)); ac++;
430 XtSetValues(file_namelbl, al, ac);
431
432 /* Change the icon */
433 ac=0;
434 XtSetArg(al[ac], XmNiconName,pc); ac++;
435 XtSetValues(toplevel,al,ac);
436
437 /* Put a separator in the text Window */
438 ac=0;
439 nbcol=10;
440 XtSetArg(al[ac], XmNcolumns,&nbcol); ac++;
441 XtGetValues(text,al,ac);
442
443 for (i=0;i<nbcol;i++)
444 separator[i]='*';
445 separator[i]='\0';
446
447 XmTextInsert(text,wpr_position, separator);
448 wpr_position+= strlen(separator);
449 XmTextInsert(text,wpr_position++,"\n");
450 XtVaSetValues(text,XmNcursorPosition, wpr_position,NULL);
451 XmTextShowPosition(text,wpr_position);
452 }
453 break;
454
455 case FILE_LIST_MESSAGE : {
456 char filename[255];
457 int i, number_of_files;
458 XmString s;
459
460 /* reset the playing list : play from the start */
461 file_number_to_play=0;
462
463 m_pipe_int_read(&number_of_files);
464
465 for (i=0;i<number_of_files;i++)
466 {
467 m_pipe_string_read(filename);
468 s=XmStringCreate(filename,char_set);
469 XmListAddItemUnselected(file_list,s,0);
470 XmStringFree(s);
471 }
472 }
473 break;
474
475 case ERROR_MESSAGE :
476 case NEXT_FILE_MESSAGE :
477 case PREV_FILE_MESSAGE :
478 case TUNE_END_MESSAGE :{
479 Arg al[10];
480 int ac;
481 int nbfile;
482 XmStringTable files;
483
484 /* When a file ends, launch next if auto_next toggle */
485 if ((message==TUNE_END_MESSAGE) &&
486 !XmToggleButtonGetState(auto_next_option))
487 return;
488
489 /* Total number of file to play in the list */
490 ac=0;
491 XtSetArg(al[ac], XmNitemCount, &nbfile); ac++;
492 XtGetValues(file_list, al, ac);
493 XmListDeselectAllItems(file_list);
494
495 if (message==NEXT_FILE_MESSAGE||message==TUNE_END_MESSAGE)
496 file_number_to_play++;
497 else if (message==PREV_FILE_MESSAGE)
498 file_number_to_play--;
499 else
500 {
501 ac=0;
502 XtSetArg(al[ac], XmNitems, &files); ac++;
503 XtGetValues(file_list, al, ac);
504 XmListDeleteItem(file_list, files[file_number_to_play-1]);
505 XmListSelectPos(file_list,file_number_to_play,TRUE);
506 return;
507 }
508
509 /* Do nothing if requested file is before first one */
510 if (file_number_to_play<=0)
511 {
512 file_number_to_play=0;
513 XmScaleSetValue(locator_scale,0);
514 return;
515 }
516
517 /* Stop after playing the last file */
518 if (file_number_to_play>nbfile)
519 {
520 file_number_to_play=nbfile+1;
521 XmScaleSetValue(locator_scale,0);
522 return;
523 }
524
525 XmListSelectPos(file_list,file_number_to_play,TRUE);
526 }
527 break;
528
529 case CURTIME_MESSAGE : {
530 int tseconds;
531 int sec,seconds, minutes;
532 int nbvoice;
533 char local_string[20];
534 Arg al[10];
535 int ac;
536
537 m_pipe_int_read(&tseconds);
538 m_pipe_int_read(&nbvoice);
539
540 sec=seconds=tseconds;
541
542 /* To avoid blinking */
543 if (sec!=last_sec)
544 {
545 minutes=seconds/60;
546 seconds-=minutes*60;
547
548 sprintf(local_string,"%02d:%02d",
549 minutes, seconds);
550
551 ac=0;
552 XtSetArg(al[ac], XmNlabelString,
553 XmStringCreate(local_string, char_set)); ac++;
554 XtSetValues(counterlbl, al, ac);
555 }
556
557 last_sec=sec;
558
559 /* Readjust the time scale if not dragging the scale */
560 if ( (locator_scale_button==ButtonRelease) &&
561 (tseconds<max_sec))
562 XmScaleSetValue(locator_scale, tseconds);
563 }
564 break;
565
566 case NOTE_MESSAGE : {
567 int channel;
568 int note;
569
570 m_pipe_int_read(&channel);
571 m_pipe_int_read(¬e);
572 #ifdef DEBUG
573 fprintf(stderr, "NOTE chn%i %i\n",channel,note);
574 #endif /* DEBUG */
575 }
576 break;
577
578 case PROGRAM_MESSAGE :{
579 int channel;
580 int pgm;
581
582 m_pipe_int_read(&channel);
583 m_pipe_int_read(&pgm);
584 #ifdef DEBUG
585 fprintf(stderr, "NOTE chn%i %i\n",channel,pgm);
586 #endif /* DEBUG */
587 }
588 break;
589
590 case VOLUME_MESSAGE : {
591 int channel;
592 int volume;
593
594 m_pipe_int_read(&channel);
595 m_pipe_int_read(&volume);
596 #ifdef DEBUG
597 fprintf(stderr, "VOLUME= chn%i %i \n",channel, volume);
598 #endif /* DEBUG */
599 }
600 break;
601
602
603 case EXPRESSION_MESSAGE : {
604 int channel;
605 int express;
606
607 m_pipe_int_read(&channel);
608 m_pipe_int_read(&express);
609 #ifdef DEBUG
610 fprintf(stderr, "EXPRESSION= chn%i %i \n",channel, express);
611 #endif /* DEBUG */
612 }
613 break;
614
615 case PANNING_MESSAGE : {
616 int channel;
617 int pan;
618
619 m_pipe_int_read(&channel);
620 m_pipe_int_read(&pan);
621 #ifdef DEBUG
622 fprintf(stderr, "PANNING= chn%i %i \n",channel, pan);
623 #endif /* DEBUG */
624 }
625 break;
626
627 case SUSTAIN_MESSAGE : {
628 int channel;
629 int sust;
630
631 m_pipe_int_read(&channel);
632 m_pipe_int_read(&sust);
633 #ifdef DEBUG
634 fprintf(stderr, "SUSTAIN= chn%i %i \n",channel, sust);
635 #endif /* DEBUG */
636 }
637 break;
638
639 case PITCH_MESSAGE : {
640 int channel;
641 int bend;
642
643 m_pipe_int_read(&channel);
644 m_pipe_int_read(&bend);
645 #ifdef DEBUG
646 fprintf(stderr, "PITCH BEND= chn%i %i \n",channel, bend);
647 #endif /* DEBUG */
648 }
649 break;
650
651 case RESET_MESSAGE : {
652 #ifdef DEBUG
653 fprintf(stderr, "RESET_MESSAGE\n");
654 #endif /* DEBUG */
655 }
656 break;
657
658 case CLOSE_MESSAGE : {
659 #ifdef DEBUG
660 fprintf(stderr, "CLOSE_MESSAGE\n");
661 #endif /* DEBUG */
662 exit(0);
663 }
664 break;
665
666 case CMSG_MESSAGE : {
667 int type;
668 char message[1000];
669
670 m_pipe_int_read(&type);
671 m_pipe_string_read(message);
672
673 XmTextInsert(text,wpr_position, message);
674 wpr_position+= strlen(message);
675 XmTextInsert(text,wpr_position++, "\n");
676 XtVaSetValues(text,XmNcursorPosition, wpr_position,NULL);
677 XmTextShowPosition(text,wpr_position);
678 }
679 break;
680 case LYRIC_MESSAGE : {
681 char message[1000];
682
683 m_pipe_string_read(message);
684
685 XmTextInsert(text, wpr_position, message);
686 wpr_position += strlen(message);
687 XtVaSetValues(text,XmNcursorPosition, wpr_position,NULL);
688 XmTextShowPosition(text,wpr_position);
689 XmTextInsert(text,wpr_position, ""); /* Update cursor */
690 }
691 break;
692 default:
693 fprintf(stderr,"UNKNOW MOTIF MESSAGE %i" NLS, message);
694 }
695
696 }
697
698 /* ***************************************
699 * *
700 * Convenience function to create menus *
701 * *
702 *****************************************/
703
704 /* adds an accelerator to a menu option. */
add_accelerator(Widget w,char * acc_text,char * key)705 static void add_accelerator(Widget w,char *acc_text,char *key)
706 {
707 int ac;
708 Arg al[10];
709
710 ac=0;
711 XtSetArg(al[ac],XmNacceleratorText,
712 XmStringCreate(acc_text,char_set)); ac++;
713 XtSetArg(al[ac],XmNaccelerator,key); ac++;
714 XtSetValues(w,al,ac);
715 }
716
717 /* Adds a toggle option to an existing menu. */
make_menu_toggle(char * item_name,int client_data,Widget menu)718 static Widget make_menu_toggle(char *item_name, int client_data, Widget menu)
719 {
720 int ac;
721 Arg al[10];
722 Widget item;
723
724 ac = 0;
725 XtSetArg(al[ac],XmNlabelString, XmStringCreateLtoR(item_name,
726 char_set)); ac++;
727 item=XmCreateToggleButton(menu,item_name,al,ac);
728 XtManageChild(item);
729 XtAddCallback(item, XmNvalueChangedCallback,
730 (XtCallbackProc) menuCB,(XtPointer) client_data);
731 XtSetSensitive(item, True);
732 return(item);
733 }
734
735 /* Adds an option to an existing menu. */
make_menu_option(char * option_name,KeySym mnemonic,int client_data,Widget menu)736 static Widget make_menu_option(char *option_name, KeySym mnemonic,
737 int client_data, Widget menu)
738 {
739 int ac;
740 Arg al[10];
741 Widget b;
742
743 ac = 0;
744 XtSetArg(al[ac], XmNlabelString,
745 XmStringCreateLtoR(option_name, char_set)); ac++;
746 XtSetArg (al[ac], XmNmnemonic, mnemonic); ac++;
747 b=XtCreateManagedWidget(option_name,xmPushButtonWidgetClass,
748 menu,al,ac);
749 XtAddCallback (b, XmNactivateCallback,
750 (XtCallbackProc) menuCB, (XtPointer) client_data);
751 return(b);
752 }
753
754 /* Creates a new menu on the menu bar. */
make_menu(char * menu_name,KeySym mnemonic,Widget menu_bar)755 static Widget make_menu(char *menu_name,KeySym mnemonic, Widget menu_bar)
756 {
757 int ac;
758 Arg al[10];
759 Widget menu, cascade;
760
761 ac = 0;
762 menu = XmCreatePulldownMenu (menu_bar, menu_name, al, ac);
763
764 ac = 0;
765 XtSetArg (al[ac], XmNsubMenuId, menu); ac++;
766 XtSetArg (al[ac], XmNmnemonic, mnemonic); ac++;
767 XtSetArg(al[ac], XmNlabelString,
768 XmStringCreateLtoR(menu_name, char_set)); ac++;
769 cascade = XmCreateCascadeButton (menu_bar, menu_name, al, ac);
770 XtManageChild (cascade);
771
772 return(menu);
773 }
774
775 /* *******************************************
776 * *
777 * Interface initialisation before launching *
778 * *
779 *********************************************/
780
create_menus(Widget menu_bar)781 static void create_menus(Widget menu_bar)
782 {
783 Widget menu;
784
785 menu=make_menu("File",'F',menu_bar);
786 open_option = make_menu_option("Open", 'O', MENU_OPEN, menu);
787 add_accelerator(open_option, "meta+o", "Meta<Key>o:");
788
789 quit_option = make_menu_option("Exit", 'E', MENU_QUIT, menu);
790 add_accelerator(quit_option, "meta+q", "Meta<Key>q:");
791
792 menu=make_menu("Options",'O',menu_bar);
793 auto_next_option= make_menu_toggle("Auto Next", MENU_TOGGLE, menu);
794 XmToggleButtonSetState( auto_next_option , True , False );
795 }
796
create_dialog_boxes(void)797 static void create_dialog_boxes(void)
798 {
799 Arg al[10];
800 int ac;
801 XmString add_all = XmStringCreateLocalized("ADD ALL");
802
803 /* create the file selection box used by MENU_OPEN */
804 ac=0;
805 XtSetArg(al[ac],XmNmustMatch,True); ac++;
806 XtSetArg(al[ac],XmNautoUnmanage,False); ac++;
807 XtSetArg(al[ac],XmNdialogTitle,
808 XmStringCreateLtoR("TIMIDITY: Open",char_set)); ac++;
809 open_dialog=XmCreateFileSelectionDialog(toplevel,"open_dialog",al,ac);
810 XtAddCallback(open_dialog, XmNokCallback,
811 (XtCallbackProc) openCB, (XtPointer) DIALOG_OK);
812 XtAddCallback(open_dialog, XmNcancelCallback,
813 (XtCallbackProc) openCB, (XtPointer) DIALOG_CANCEL);
814 XtUnmanageChild(XmFileSelectionBoxGetChild(open_dialog, XmDIALOG_HELP_BUTTON));
815
816 ac = 0;
817 XtSetArg(al[ac], XmNleftOffset, 10); ac++;
818 XtSetArg(al[ac], XmNrightOffset, 10); ac++;
819 XtSetArg(al[ac], XmNtopOffset, 10); ac++;
820 XtSetArg(al[ac], XmNbottomOffset, 10); ac++;
821 XtSetArg(al[ac], XmNlabelString, add_all); ac++;
822 add_all_button = XmCreatePushButton(open_dialog, "add_all",al, ac);
823 XtManageChild(add_all_button);
824 XtAddCallback(add_all_button, XmNactivateCallback,
825 (XtCallbackProc) openCB, (XtPointer) DIALOG_ALL);
826 }
827
Launch_Motif_Process(int pipe_number)828 void Launch_Motif_Process(int pipe_number)
829 {
830 Arg al[20];
831 int ac;
832 int argc=0;
833
834 XtSetLanguageProc(NULL,NULL,NULL); /* By KINOSHITA, K. <kino@krhm.jvc-victor.co.jp> */
835
836 /* create the toplevel shell */
837 toplevel = XtAppInitialize(&context,"timidity",NULL,0,&argc,NULL,
838 NULL,NULL,0);
839
840 /*******************/
841 /* Main form */
842 /*******************/
843 ac=0;
844 XtSetArg(al[ac],XmNtopAttachment,XmATTACH_FORM); ac++;
845 XtSetArg(al[ac],XmNbottomAttachment,XmATTACH_FORM); ac++;
846 XtSetArg(al[ac],XmNrightAttachment,XmATTACH_FORM); ac++;
847 XtSetArg(al[ac],XmNleftAttachment,XmATTACH_FORM); ac++;
848
849 mainForm=XmCreateForm(toplevel,"form",al,ac);
850 XtManageChild(mainForm);
851
852 CreatePixmaps(mainForm);
853
854
855 /* create a menu bar and attach it to the form. */
856 ac=0;
857 XtSetArg(al[ac], XmNtopAttachment, XmATTACH_FORM); ac++;
858 XtSetArg(al[ac], XmNrightAttachment, XmATTACH_FORM); ac++;
859 XtSetArg(al[ac], XmNleftAttachment, XmATTACH_FORM); ac++;
860 menu_bar=XmCreateMenuBar(mainForm,"menu_bar",al,ac);
861 XtManageChild(menu_bar);
862
863 create_dialog_boxes();
864 create_menus(menu_bar);
865
866 /*******************/
867 /* Message window */
868 /*******************/
869
870 ac=0;
871 XtSetArg(al[ac], XmNleftOffset, 10); ac++;
872 XtSetArg(al[ac], XmNrightOffset, 10); ac++;
873 XtSetArg(al[ac], XmNtopOffset, 10); ac++;
874 XtSetArg(al[ac], XmNbottomOffset, 10); ac++;
875 XtSetArg(al[ac],XmNtopAttachment,XmATTACH_WIDGET); ac++;
876 XtSetArg(al[ac],XmNtopWidget, menu_bar); ac++;
877 XtSetArg(al[ac],XmNrightAttachment,XmATTACH_FORM); ac++;
878 XtSetArg(al[ac],XmNleftAttachment,XmATTACH_FORM); ac++;
879 XtSetArg(al[ac],XmNeditMode,XmMULTI_LINE_EDIT); ac++;
880 XtSetArg(al[ac],XmNrows,10); ac++;
881 XtSetArg(al[ac],XmNcolumns,10); ac++;
882 XtSetArg(al[ac],XmNeditable, False); ac++;
883 XtSetArg(al[ac],XmNwordWrap, True); ac++;
884 XtSetArg(al[ac],XmNvalue, "TIMIDIY RUNNING...\n"); ac++;
885 wpr_position+= strlen("TIMIDIY RUNNING...\n");
886
887 text=XmCreateScrolledText(mainForm,"text",al,ac);
888 XtManageChild(text);
889
890 /********************/
891 /* File_name label */
892 /********************/
893 ac = 0;
894 XtSetArg(al[ac], XmNleftOffset, 20); ac++;
895 XtSetArg(al[ac], XmNrightOffset, 10); ac++;
896 XtSetArg(al[ac], XmNtopOffset, 20); ac++;
897 XtSetArg(al[ac], XmNbottomOffset, 20); ac++;
898 XtSetArg(al[ac], XmNlabelType, XmSTRING); ac++;
899 XtSetArg(al[ac], XmNtopAttachment, XmATTACH_WIDGET); ac++;
900 XtSetArg(al[ac], XmNtopWidget, text); ac++;
901 XtSetArg(al[ac], XmNleftAttachment,XmATTACH_FORM); ac++;
902 XtSetArg(al[ac], XmNtraversalOn, False); ac++;
903 XtSetArg(al[ac], XmNhighlightThickness,0); ac++;
904 XtSetArg(al[ac], XmNalignment,XmALIGNMENT_END); ac++;
905 XtSetArg(al[ac], XmNlabelString,
906 XmStringCreate("Playing:",char_set)); ac++;
907 file_headlbl = XmCreateLabel(mainForm,"fileheadlbl",al,ac);
908 XtManageChild(file_headlbl);
909
910
911 ac = 0;
912 XtSetArg(al[ac], XmNrightOffset, 10); ac++;
913 XtSetArg(al[ac], XmNtopOffset, 20); ac++;
914 XtSetArg(al[ac], XmNbottomOffset, 20); ac++;
915 XtSetArg(al[ac], XmNlabelType, XmSTRING); ac++;
916 XtSetArg(al[ac], XmNtopAttachment, XmATTACH_WIDGET); ac++;
917 XtSetArg(al[ac], XmNtopWidget, text); ac++;
918 XtSetArg(al[ac], XmNleftAttachment,XmATTACH_WIDGET); ac++;
919 XtSetArg(al[ac], XmNleftWidget,file_headlbl); ac++;
920 XtSetArg(al[ac], XmNtraversalOn, False); ac++;
921 XtSetArg(al[ac], XmNhighlightThickness,0); ac++;
922 XtSetArg(al[ac], XmNalignment,XmALIGNMENT_BEGINNING); ac++;
923 XtSetArg(al[ac], XmNlabelString,
924 XmStringCreate("NONE ",char_set)); ac++;
925 file_namelbl = XmCreateLabel(mainForm,"filenameLbl",al,ac);
926 XtManageChild(file_namelbl);
927
928 /*****************************/
929 /* TIME LABELS IN A FORM */
930 /*****************************/
931
932 /* Counters frame */
933 ac=0;
934 XtSetArg(al[ac], XmNtopOffset, 10); ac++;
935 XtSetArg(al[ac], XmNbottomOffset, 10); ac++;
936 XtSetArg(al[ac], XmNleftOffset, 10); ac++;
937 XtSetArg(al[ac], XmNrightOffset, 10); ac++;
938 XtSetArg(al[ac],XmNtopAttachment,XmATTACH_WIDGET); ac++;
939 XtSetArg(al[ac],XmNtopWidget,text); ac++;
940 XtSetArg(al[ac],XmNrightAttachment,XmATTACH_FORM); ac++;
941 /*
942 XtSetArg(al[ac],XmNleftAttachment,XmATTACH_WIDGET); ac++;
943 XtSetArg(al[ac],XmNleftWidget,file_namelbl); ac++;
944 */
945 XtSetArg(al[ac],XmNshadowType,XmSHADOW_OUT); ac++;
946 countFrame=XmCreateFrame(mainForm,"countframe",al,ac);
947 XtManageChild(countFrame);
948
949 /* Counters form */
950 ac=0;
951 XtSetArg(al[ac],XmNtopAttachment,XmATTACH_FORM); ac++;
952 XtSetArg(al[ac],XmNbottomAttachment,XmATTACH_FORM); ac++;
953 XtSetArg(al[ac],XmNrightAttachment,XmATTACH_FORM); ac++;
954 XtSetArg(al[ac],XmNleftAttachment,XmATTACH_FORM); ac++;
955 XtSetArg(al[ac],XmNleftAttachment,XmATTACH_FORM); ac++;
956
957 countForm=XmCreateForm(countFrame,"countform",al,ac);
958 XtManageChild(countForm);
959
960 /* HEADER label */
961 ac = 0;
962 XtSetArg(al[ac], XmNtopOffset, 10); ac++;
963 XtSetArg(al[ac], XmNlabelType, XmSTRING); ac++;
964 XtSetArg(al[ac], XmNtopAttachment, XmATTACH_FORM); ac++;
965 XtSetArg(al[ac], XmNleftAttachment,XmATTACH_FORM); ac++;
966 XtSetArg(al[ac], XmNrightAttachment,XmATTACH_FORM); ac++;
967 XtSetArg(al[ac], XmNtraversalOn, False); ac++;
968 XtSetArg(al[ac], XmNhighlightThickness,0); ac++;
969 XtSetArg(al[ac], XmNlabelString,
970 XmStringCreate("Time:",char_set)); ac++;
971 count_headlbl = XmCreateLabel(countForm,"countheadLbl",al,ac);
972 XtManageChild(count_headlbl);
973
974 /* current Time label */
975 ac = 0;
976 XtSetArg(al[ac], XmNtopAttachment, XmATTACH_WIDGET); ac++;
977 XtSetArg(al[ac], XmNtopWidget, count_headlbl); ac++;
978 XtSetArg(al[ac], XmNleftAttachment,XmATTACH_FORM); ac++;
979 XtSetArg(al[ac], XmNbottomAttachment,XmATTACH_FORM); ac++;
980 XtSetArg(al[ac], XmNtraversalOn, False); ac++;
981 XtSetArg(al[ac], XmNhighlightThickness,0); ac++;
982 XtSetArg(al[ac], XmNalignment,XmALIGNMENT_END); ac++;
983 XtSetArg(al[ac], XmNlabelString,
984 XmStringCreate("00:00",char_set)); ac++;
985 counterlbl = XmCreateLabel(countForm,"counterLbl",al,ac);
986 XtManageChild(counterlbl);
987
988 /* Total time label */
989
990 ac = 0;
991 XtSetArg(al[ac], XmNtopAttachment, XmATTACH_WIDGET); ac++;
992 XtSetArg(al[ac], XmNtopWidget, count_headlbl); ac++;
993 XtSetArg(al[ac], XmNleftAttachment, XmATTACH_WIDGET); ac++;
994 XtSetArg(al[ac], XmNleftWidget, counterlbl); ac++;
995 XtSetArg(al[ac], XmNrightAttachment, XmATTACH_FORM); ac++;
996 XtSetArg(al[ac], XmNbottomAttachment,XmATTACH_FORM); ac++;
997 XtSetArg(al[ac], XmNtraversalOn, False); ac++;
998 XtSetArg(al[ac], XmNhighlightThickness,0); ac++;
999 XtSetArg(al[ac], XmNalignment,XmALIGNMENT_BEGINNING); ac++;
1000 XtSetArg(al[ac], XmNlabelString,
1001 XmStringCreate("/ 00:00",char_set)); ac++;
1002 totlbl = XmCreateLabel(countForm,"TotalTimeLbl",al,ac);
1003 XtManageChild(totlbl);
1004
1005 /******************/
1006 /* Locator Scale */
1007 /******************/
1008 { /*
1009 * We need to add an xevent manager for buton pressing since
1010 * locator_scale is a critical ressource that can be modified
1011 * by shared by the handle input function
1012 */
1013
1014 WidgetList WList;
1015 Cardinal Card;
1016
1017 ac = 0;
1018 XtSetArg(al[ac], XmNleftOffset, 10); ac++;
1019 XtSetArg(al[ac], XmNrightOffset, 10); ac++;
1020 XtSetArg(al[ac], XmNtopOffset, 10); ac++;
1021 XtSetArg(al[ac], XmNbottomOffset, 10); ac++;
1022 XtSetArg(al[ac], XmNtopAttachment, XmATTACH_WIDGET); ac++;
1023 XtSetArg(al[ac], XmNtopWidget, countForm); ac++;
1024 XtSetArg(al[ac], XmNleftAttachment,XmATTACH_FORM); ac++;
1025 XtSetArg(al[ac], XmNrightAttachment,XmATTACH_FORM); ac++;
1026 XtSetArg(al[ac], XmNmaximum, 100); ac++;
1027 XtSetArg(al[ac], XmNminimum, 0); ac++;
1028 XtSetArg(al[ac], XmNshowValue, True); ac++;
1029 XtSetArg(al[ac], XmNdecimalPoints, 0); ac++;
1030 XtSetArg(al[ac], XmNorientation, XmHORIZONTAL); ac++;
1031 XtSetArg(al[ac], XmNtraversalOn, False); ac++;
1032 XtSetArg(al[ac], XmNhighlightThickness,0); ac++;
1033 locator_scale = XmCreateScale(mainForm,"locator",al,ac);
1034 XtManageChild(locator_scale);
1035 XtAddCallback(locator_scale,XmNvalueChangedCallback,
1036 (XtCallbackProc) Generic_scaleCB,
1037 (XtPointer) MOTIF_CHANGE_LOCATOR);
1038
1039 /* Reach the scrollbar child in the scale */
1040 ac = 0;
1041 XtSetArg(al[ac], XtNchildren, &WList); ac++;
1042 XtSetArg(al[ac], XtNnumChildren, &Card); ac++;
1043 XtGetValues(locator_scale,al,ac);
1044 if ((Card!=2)||
1045 strcmp(XtName(WList[1]),"Scrollbar"))
1046 fprintf(stderr,"PANIC: Scale has be redefined.. may cause bugs\n");
1047
1048 XtAddEventHandler(WList[1],ButtonPressMask|ButtonReleaseMask,
1049 FALSE,Locator_btn,NULL);
1050 }
1051
1052 /*****************************/
1053 /* Control buttons in a form */
1054 /*****************************/
1055
1056 /* create form for the row of control buttons */
1057 ac = 0;
1058 XtSetArg(al[ac], XmNtopOffset, 10); ac++;
1059 XtSetArg(al[ac], XmNbottomOffset, 10); ac++;
1060 XtSetArg(al[ac], XmNleftAttachment, XmATTACH_FORM); ac++;
1061 /* XtSetArg(al[ac], XmNrightAttachment, XmATTACH_FORM); ac++; */
1062 XtSetArg(al[ac],XmNtopAttachment,XmATTACH_WIDGET); ac++;
1063 XtSetArg(al[ac], XmNtopWidget, locator_scale); ac++;
1064 btnForm = XmCreateForm(mainForm,"btnForm", al, ac);
1065 XtManageChild(btnForm);
1066
1067 /* Previous Button */
1068 ac = 0;
1069 XtSetArg(al[ac], XmNtopAttachment, XmATTACH_FORM); ac++;
1070 XtSetArg(al[ac], XmNleftAttachment, XmATTACH_FORM); ac++;
1071 XtSetArg(al[ac], XmNleftOffset, 10); ac++;
1072 XtSetArg(al[ac], XmNshadowType, XmSHADOW_OUT); ac++;
1073 XtSetArg(al[ac], XmNshadowThickness, 2); ac++;
1074 XtSetArg(al[ac], XmNlabelType, XmPIXMAP); ac++;
1075 XtSetArg(al[ac], XmNlabelPixmap, prevPixmap); ac++;
1076 XtSetArg(al[ac], XmNhighlightThickness, 2); ac++;
1077 prevBtn = XmCreatePushButton(btnForm, "previous",al, ac);
1078 XtManageChild(prevBtn);
1079 XtAddCallback(prevBtn, XmNactivateCallback,
1080 (XtCallbackProc) GenericCB, (XtPointer) MOTIF_PREV);
1081
1082
1083 /* Backward Button */
1084 ac = 0;
1085 XtSetArg(al[ac], XmNtopAttachment, XmATTACH_FORM); ac++;
1086 XtSetArg(al[ac], XmNleftAttachment, XmATTACH_WIDGET); ac++;
1087 XtSetArg(al[ac], XmNleftWidget, prevBtn); ac++;
1088 XtSetArg(al[ac], XmNleftOffset, 2); ac++;
1089 XtSetArg(al[ac], XmNshadowType, XmSHADOW_OUT); ac++;
1090 XtSetArg(al[ac], XmNshadowThickness, 2); ac++;
1091 XtSetArg(al[ac], XmNlabelType, XmPIXMAP); ac++;
1092 XtSetArg(al[ac], XmNlabelPixmap, backPixmap); ac++;
1093 XtSetArg(al[ac], XmNhighlightThickness, 2); ac++;
1094 backBtn = XmCreatePushButton(btnForm, "backward",al, ac);
1095 XtManageChild(backBtn);
1096 XtAddCallback(backBtn, XmNactivateCallback,
1097 (XtCallbackProc) GenericCB, (XtPointer) MOTIF_RWD);
1098
1099 /* Restart Button */
1100 ac = 0;
1101 XtSetArg(al[ac], XmNtopAttachment, XmATTACH_FORM); ac++;
1102 XtSetArg(al[ac], XmNleftAttachment, XmATTACH_WIDGET); ac++;
1103 XtSetArg(al[ac], XmNleftWidget, backBtn); ac++;
1104 XtSetArg(al[ac], XmNleftOffset, 2); ac++;
1105 XtSetArg(al[ac], XmNshadowType, XmSHADOW_OUT); ac++;
1106 XtSetArg(al[ac], XmNshadowThickness, 2); ac++;
1107 XtSetArg(al[ac], XmNlabelType, XmPIXMAP); ac++;
1108 XtSetArg(al[ac], XmNlabelPixmap, restartPixmap); ac++;
1109 XtSetArg(al[ac], XmNhighlightThickness, 2); ac++;
1110 restartBtn = XmCreatePushButton(btnForm,"restartBtn", al, ac);
1111 XtManageChild(restartBtn);
1112 XtAddCallback(restartBtn, XmNactivateCallback,
1113 (XtCallbackProc) GenericCB, (XtPointer) MOTIF_RESTART);
1114
1115 /* Quit Button */
1116 ac = 0;
1117 XtSetArg(al[ac], XmNtopAttachment, XmATTACH_FORM); ac++;
1118 XtSetArg(al[ac], XmNleftAttachment, XmATTACH_WIDGET); ac++;
1119 XtSetArg(al[ac], XmNleftWidget, restartBtn); ac++;
1120 XtSetArg(al[ac], XmNleftOffset, 2); ac++;
1121 XtSetArg(al[ac], XmNshadowType, XmSHADOW_OUT); ac++;
1122 XtSetArg(al[ac], XmNshadowThickness, 2); ac++;
1123 XtSetArg(al[ac], XmNlabelType, XmPIXMAP); ac++;
1124 XtSetArg(al[ac], XmNlabelPixmap, quitPixmap); ac++;
1125 XtSetArg(al[ac], XmNhighlightThickness, 2); ac++;
1126 quitBtn = XmCreatePushButton(btnForm,"quitBtn", al, ac);
1127 XtManageChild(quitBtn);
1128 XtAddCallback(quitBtn, XmNactivateCallback,
1129 (XtCallbackProc) GenericCB, (XtPointer) MOTIF_QUIT);
1130
1131 /* Pause Button */
1132
1133 ac = 0;
1134 XtSetArg(al[ac], XmNtopAttachment, XmATTACH_FORM); ac++;
1135 XtSetArg(al[ac], XmNleftAttachment, XmATTACH_WIDGET); ac++;
1136 XtSetArg(al[ac], XmNleftWidget, quitBtn); ac++;
1137 XtSetArg(al[ac], XmNshadowType, XmSHADOW_OUT); ac++;
1138 XtSetArg(al[ac], XmNshadowThickness, 2); ac++;
1139 XtSetArg(al[ac], XmNlabelType, XmPIXMAP); ac++;
1140 XtSetArg(al[ac], XmNlabelPixmap, pausePixmap); ac++;
1141 XtSetArg(al[ac], XmNhighlightThickness, 2); ac++;
1142 pauseBtn = XmCreatePushButton(btnForm,"pauseBtn", al, ac);
1143 XtManageChild(pauseBtn);
1144 XtAddCallback(pauseBtn, XmNactivateCallback,
1145 (XtCallbackProc) GenericCB,(XtPointer) MOTIF_PAUSE);
1146
1147 /* Forward Button */
1148
1149 ac = 0;
1150 XtSetArg(al[ac], XmNtopAttachment, XmATTACH_FORM); ac++;
1151 XtSetArg(al[ac], XmNleftAttachment, XmATTACH_WIDGET); ac++;
1152 XtSetArg(al[ac], XmNleftWidget,pauseBtn); ac++;
1153 XtSetArg(al[ac], XmNshadowType, XmSHADOW_OUT); ac++;
1154 XtSetArg(al[ac], XmNshadowThickness, 2); ac++;
1155 XtSetArg(al[ac], XmNlabelType, XmPIXMAP); ac++;
1156 XtSetArg(al[ac], XmNlabelPixmap, fwdPixmap); ac++;
1157 XtSetArg(al[ac], XmNhighlightThickness, 2); ac++;
1158 fwdBtn = XmCreatePushButton(btnForm,"fwdBtn", al, ac);
1159 XtManageChild(fwdBtn);
1160 XtAddCallback(fwdBtn, XmNactivateCallback,
1161 (XtCallbackProc) GenericCB, (XtPointer) MOTIF_FWD);
1162
1163 /* Next Button */
1164 ac = 0;
1165 XtSetArg(al[ac], XmNtopAttachment, XmATTACH_FORM); ac++;
1166 XtSetArg(al[ac], XmNrightAttachment, XmATTACH_FORM); ac++;
1167 XtSetArg(al[ac], XmNleftAttachment, XmATTACH_WIDGET); ac++;
1168 XtSetArg(al[ac], XmNleftWidget, fwdBtn); ac++;
1169 XtSetArg(al[ac], XmNleftOffset, 2); ac++;
1170 XtSetArg(al[ac], XmNshadowType, XmSHADOW_OUT); ac++;
1171 XtSetArg(al[ac], XmNshadowThickness, 2); ac++;
1172 XtSetArg(al[ac], XmNlabelType, XmPIXMAP); ac++;
1173 XtSetArg(al[ac], XmNlabelPixmap, nextPixmap); ac++;
1174 XtSetArg(al[ac], XmNhighlightThickness, 2); ac++;
1175 nextBtn = XmCreatePushButton(btnForm,"nextBtn", al, ac);
1176 XtManageChild(nextBtn);
1177 XtAddCallback(nextBtn, XmNactivateCallback,
1178 (XtCallbackProc) GenericCB, (XtPointer) MOTIF_NEXT);
1179
1180 /********************/
1181 /* Volume scale */
1182 /********************/
1183 ac = 0;
1184 XtSetArg(al[ac], XmNleftOffset, 10); ac++;
1185 XtSetArg(al[ac], XmNrightOffset, 10); ac++;
1186 XtSetArg(al[ac], XmNtopOffset, 10); ac++;
1187 XtSetArg(al[ac], XmNbottomOffset, 10); ac++;
1188 XtSetArg(al[ac], XmNtopAttachment, XmATTACH_WIDGET); ac++;
1189 XtSetArg(al[ac], XmNtopWidget, btnForm); ac++;
1190 XtSetArg(al[ac], XmNleftAttachment,XmATTACH_FORM); ac++;
1191 XtSetArg(al[ac], XmNbottomAttachment,XmATTACH_FORM); ac++;
1192
1193 XtSetArg(al[ac], XmNmaximum, MAX_AMPLIFICATION); ac++;
1194 XtSetArg(al[ac], XmNminimum, 0); ac++;
1195 XtSetArg(al[ac], XmNshowValue, True); ac++;
1196
1197 XtSetArg(al[ac], XmNtraversalOn, False); ac++;
1198 XtSetArg(al[ac], XmNhighlightThickness,0); ac++;
1199 XtSetArg(al[ac], XmNtitleString,
1200 XmStringCreate("VOL",char_set)); ac++;
1201 volume_scale = XmCreateScale(mainForm,"volscale",al,ac);
1202 XtManageChild(volume_scale);
1203 XtAddCallback(volume_scale, XmNvalueChangedCallback,
1204 (XtCallbackProc) Generic_scaleCB,
1205 (XtPointer) MOTIF_CHANGE_VOLUME);
1206
1207
1208 /********************/
1209 /* File list */
1210 /********************/
1211
1212 ac = 0;
1213 XtSetArg(al[ac], XmNtopOffset, 10); ac++;
1214 XtSetArg(al[ac], XmNbottomOffset, 10); ac++;
1215 XtSetArg(al[ac], XmNleftOffset, 10); ac++;
1216 XtSetArg(al[ac], XmNrightOffset, 10); ac++;
1217 XtSetArg(al[ac], XmNtopAttachment, XmATTACH_WIDGET); ac++;
1218 XtSetArg(al[ac], XmNtopWidget, btnForm ); ac++;
1219 XtSetArg(al[ac], XmNleftAttachment,XmATTACH_WIDGET); ac++;
1220 XtSetArg(al[ac], XmNleftWidget, volume_scale); ac++;
1221 XtSetArg(al[ac], XmNrightAttachment, XmATTACH_FORM); ac++;
1222 XtSetArg(al[ac], XmNbottomAttachment,XmATTACH_FORM); ac++;
1223
1224 XtSetArg(al[ac], XmNselectionPolicy ,XmSINGLE_SELECT); ac++;
1225 XtSetArg(al[ac], XmNscrollBarDisplayPolicy ,XmAS_NEEDED); ac++;
1226 XtSetArg(al[ac], XmNlistSizePolicy ,XmRESIZE_IF_POSSIBLE); ac++;
1227
1228 XtSetArg(al[ac], XmNtraversalOn, False); ac++;
1229 XtSetArg(al[ac], XmNhighlightThickness,0); ac++;
1230
1231 file_list = XmCreateScrolledList(mainForm,"File List",al,ac);
1232 XtManageChild(file_list);
1233 XtAddCallback(file_list, XmNsingleSelectionCallback,
1234 (XtCallbackProc) File_ListCB,
1235 NULL);
1236
1237 /*
1238 * Last details on toplevel
1239 */
1240 ac=0;
1241 /*
1242 XtSetArg(al[ac],XmNwidth,400); ac++;
1243 XtSetArg(al[ac],XmNheight,800); ac++;
1244 */
1245 XtSetArg(al[ac], XmNtitle, "TiMidity"); ac++;
1246 XtSetArg(al[ac], XmNiconName, "NONE"); ac++;
1247 XtSetArg(al[ac], XmNiconPixmap, timidityPixmap); ac++;
1248 XtSetValues(toplevel,al,ac);
1249
1250
1251 /*******************************************************/
1252 /* Plug the pipe ..... and heeere we go */
1253 /*******************************************************/
1254
1255 XtAppAddInput(context,pipe_number,
1256 (XtPointer) XtInputReadMask,handle_input,NULL);
1257
1258 XtRealizeWidget(toplevel);
1259 XtAppMainLoop(context);
1260 }
1261