home *** CD-ROM | disk | FTP | other *** search
/ TOS Silver 2000 / TOS Silver 2000.iso / musik / MIDIFP21 / SOURCES / MIDI_PRT / MAIN.C < prev    next >
Encoding:
C/C++ Source or Header  |  1996-12-08  |  22.7 KB  |  694 lines

  1. /**************************************************************
  2. *
  3. *                MAIN.C
  4. *
  5. **************************************************************/
  6.  
  7. #define MIN_ZOOM 1         /* minimum zooming factor */
  8. #define MAX_ZOOM 4         /* maximum zooming factor */
  9.  
  10. #include <acs.h>
  11. #include <acsplus.h>
  12. #include <tos.h>        /* because of Dgetpath(), ... */
  13. #include <string.h>     /* because of strrchr(), ... */
  14. #include <messages.pif>   /* for use of self-built library */
  15. #include <acs_plus.pif>   /* for use of self-built library */
  16. #include <diskfile.pif>   /* for use of self-built library */
  17. #include <notimtab.pif>   /* for use of self-built library */
  18.  
  19. Awindow *MAIN_constructor(void *not_used) ;
  20. void MAIN_destructor(Awindow *wi) ;
  21. static int cdecl draw(PARMBLK *parmblk) ;
  22.  
  23. #include "main.h"
  24. #include "main.ah"
  25. #include "printer\printer.pif"
  26. #include "drawer\drawer.pif"
  27. #include "params\params.pif"
  28. #include "filter\filter.pif"
  29. #include "info\info.pif"
  30.  
  31.  
  32. /*************** GLOBAL VARIABLES BEGIN **************************/
  33.  
  34. /*** VDI handle and parameters of virtual screen workstation ***/
  35. static int screen_handle ;  
  36. static int screen_in[11] ;
  37. static int screen_out[57] ;
  38. static int number_screen_fonts ;
  39. static FONT_INFO screen_font_info[MAX_FONTS] ;
  40.  
  41. /*** VDI handle and parameters of physical printer workstation ***/
  42. static int print_handle ;  
  43. static int print_in[11] ;
  44. static int print_out[57] ;
  45. static int number_print_fonts ;
  46.  
  47. /*** path where to search for files, for all instances together ***/
  48. static char path[pathname_length] ;
  49.  
  50. /*** counter for number of constructor calls ***/
  51. int incarnation_counter = 0 ;
  52.  
  53. /*************** GLOBAL VARIABLES END ****************************/
  54.  
  55. /************* OBJECT DATA PROTOTYPE BEGIN ***********************/
  56.  
  57. typedef struct 
  58. {
  59.     Awindow *params_wi, *filter_wi, *info_wi, *drawer_wi, *printer_wi ;
  60.     char filename[filename_length], pathname[pathname_length] ;      
  61.     void *RAM_file ;
  62.     long filesize ;
  63.     int zoom ;
  64. MAIN ;
  65.  
  66. /************* OBJECT DATA PROTOTYPE END *************************/
  67.  
  68.  
  69. /*******************************************************************
  70. */
  71.     static void keys(Awindow *wi, int kstate, int key)
  72. /*  
  73. *   Keyboard procedure of the main window, see also ACS manual.
  74. *   This procedure simply forwards events to the service procedure
  75. *   of the main window and to the ACS default kayboard procedure.
  76. *
  77. *******************************************************************/
  78. {
  79.     /*** treated not here, but in service procedure ***/
  80.     key_message.sender = wi ;
  81.     key_message.kstate = kstate ;
  82.     key_message.key    = key ;
  83.     Awi_sendall(KEY_PRESS, &key_message) ;
  84.  
  85.     /*** forward event to ACS for further treatment (e.g. by the desktop) ***/
  86.     Awi_keys(wi, kstate, key) ;
  87. }
  88.  
  89. /*******************************************************************
  90. */
  91.     static void zoom_plus(Awindow *wi)
  92. /*  
  93. *   Zoom in, adapt main window size and redraw.
  94. *
  95. *******************************************************************/
  96. {
  97. MAIN *m = wi->user ;
  98.  
  99.     if (m->zoom < MAX_ZOOM) 
  100.     {
  101.         m->zoom <<= 1 ;
  102.         (wi->work)->ob_height <<= 1 ; 
  103.         (wi->work + WORK_OBJ)->ob_height <<= 1 ; 
  104.         (wi->work)->ob_width <<= 1 ; 
  105.         (wi->work + WORK_OBJ)->ob_width <<= 1 ; 
  106.         Awi_sized( wi, &(wi->wi_act) ) ;
  107.         Awi_obchange(wi, WORK_OBJ, -1) ;
  108.     }
  109. }
  110.  
  111. /*******************************************************************
  112. */
  113.     static void zoom_minus(Awindow *wi)
  114. /*  
  115. *   Zoom out, adapt main window size and redraw.
  116. *
  117. *******************************************************************/
  118. {
  119. MAIN *m = wi->user ;
  120.  
  121.     if (m->zoom > MIN_ZOOM)  
  122.     {
  123.         m->zoom >>= 1 ;
  124.         (wi->work)->ob_height >>= 1 ; 
  125.         (wi->work + WORK_OBJ)->ob_height >>= 1 ; 
  126.         (wi->work)->ob_width >>= 1 ; 
  127.         (wi->work + WORK_OBJ)->ob_width >>= 1 ; 
  128.         Awi_sized( wi, &(wi->wi_act) ) ;
  129.         Awi_obchange(wi, WORK_OBJ, -1) ;
  130.     }
  131. }
  132.  
  133. /*******************************************************************
  134. */
  135.     static int sender_test(Awindow *wi, Awindow *sender)
  136. /*  
  137. *   Returns TRUE if the sender window belongs to the own 
  138. *   incarnation, FALSE else.
  139. *
  140. *******************************************************************/
  141. {
  142. MAIN *m = wi->user ;
  143.  
  144.     if ( (sender == m->info_wi) || (sender == m->filter_wi) ||
  145.          (sender == m->params_wi) || (sender == m->drawer_wi) ||
  146.          (sender == m->printer_wi) || (sender == wi) ) return TRUE ;
  147.     else return FALSE ;
  148. }
  149.  
  150. /*******************************************************************
  151. */
  152.     static int service(Awindow *wi, int task, void *in_out)
  153. /*  
  154. *   Service procedure of the main window, see also ACS manual.
  155. *
  156. *******************************************************************/
  157. {
  158. MAIN *m = wi->user ;
  159.  
  160.     switch (task)
  161.     {
  162.     /*** ACS generated messages ***/
  163.     case AS_INFO: A_dialog(&MAIN_INFO) ; break ;
  164.     case AS_TERM: 
  165.         if (appexit || (alert_str(QUIT, m->filename) == 1)) MAIN_destructor(wi) ; 
  166.         break ; 
  167.     /*** own messages ***/
  168.     case TERMINATE: 
  169.         if (appexit) return FALSE ; /* treated under AS_TERM */
  170.         if ( !sender_test(wi, (Awindow *)in_out) ) return FALSE ;
  171.         if (alert_str(QUIT, m->filename) == 1) MAIN_destructor(wi) ; 
  172.         break ;
  173.     case REDRAW:
  174.         if ( !sender_test(wi, (Awindow *)in_out) ) return FALSE ;
  175.            stop_timer(in_out) ; /* stop delayed redraw timer job */
  176.         redraw( m->drawer_wi ) ; /* redraw immediately */
  177.         break ;
  178.     case KEY_PRESS: 
  179.         if ( !sender_test(wi, ( (KEY_MESSAGE *)in_out )->sender) ) return FALSE ;
  180.          switch( ( ( (KEY_MESSAGE *)in_out )->key & 0xFF00) )
  181.         {
  182.         case 0x4E00: /* "+" pressed on num. block */
  183.         case 0x1B00: /* "+" pressed */ 
  184.             zoom_plus(wi) ;    break ;
  185.         case 0x4A00: /* "-" pressed on num. block */
  186.         case 0x3500: /* "-" pressed */
  187.             zoom_minus(wi) ; break ;
  188.         case 0x4800: /* arrow up pressed */
  189.             select_page(m->drawer_wi, first) ; break ;
  190.         case 0x5000: /* arrow down pressed */
  191.             select_page(m->drawer_wi, last) ; break ;
  192.         case 0x4B00: /* arrow left pressed */
  193.             select_page(m->drawer_wi, previous) ; break ;
  194.         case 0x4D00: /* arrow right pressed */
  195.             select_page(m->drawer_wi, next) ; break ;
  196.         }
  197.         break ;
  198.     case ZOOM_PLUS:  
  199.         if ( !sender_test(wi, (Awindow *)in_out) ) return FALSE ;
  200.         zoom_plus(wi) ;  
  201.         break ;
  202.     case ZOOM_MINUS: 
  203.         if ( !sender_test(wi, (Awindow *)in_out) ) return FALSE ;
  204.         zoom_minus(wi) ; 
  205.         break ;
  206.     default: return FALSE ;
  207.     }
  208.     return TRUE ;
  209. }
  210.  
  211.  
  212. /******************************************************************
  213. */ 
  214.     static int cdecl draw(PARMBLK *parmblk) 
  215. /*
  216. *    GEM drawing routine for the user defined 
  217. *    GEM object in the main window. 
  218. *******************************************************************/
  219. {
  220. MAIN *m = (MAIN *)parmblk->pb_parm ;
  221. int points[4] ;
  222.  
  223.     /*** set clipping rectangle ***/
  224.     points[0] = parmblk->pb_xc ; 
  225.     points[1] = parmblk->pb_yc ; 
  226.     points[2] = points[0] + parmblk->pb_wc - 1 ;
  227.     points[3] = points[1] + parmblk->pb_hc - 1 ;
  228.     vs_clip(screen_handle, 1, points) ;    
  229.  
  230.     /*** draw background ***/
  231.     vsf_color(screen_handle, WHITE) ;
  232.     vr_recfl(screen_handle, points) ;
  233.  
  234.     /*** draw note systems ***/
  235.     if (m->drawer_wi)
  236.         draw_page( screen_handle, m->drawer_wi, parmblk->pb_x, parmblk->pb_y, 
  237.                    points, m->zoom, get_current_page(m->drawer_wi) ) ;
  238.     /*** reset clipping ***/
  239.     vs_clip(screen_handle, 0, points) ;
  240.  
  241.     /*** return object state unchanged ***/
  242.     return(parmblk->pb_prevstate) ;          
  243. }
  244.  
  245.  
  246. /********************************************************************
  247. */
  248.     static void MAIN_destructor(Awindow *wi)
  249. /*
  250. *   Destructor of the MAIN object. It
  251. *   frees all memory used by ACS and own data instances.
  252. ********************************************************************/
  253. {
  254. MAIN *m ;
  255.  
  256.     /*** incarnation counter: here a work-around. ACS sends messages
  257.          to windows already deleted ?! ***/
  258.     if (wi && incarnation_counter) {
  259.         m = wi->user ;
  260.         if (m) {
  261.             /*** instances of sub-objects ***/
  262.             PRINTER_destructor(m->printer_wi) ;
  263.             DRAWER_destructor(m->drawer_wi) ;
  264.             PARAMS_destructor(m->params_wi) ;
  265.             FILTER_destructor(m->filter_wi) ;
  266.             INFO_destructor(m->info_wi) ;
  267.  
  268.             /*** own object instance ***/
  269.             if (m->RAM_file) unload_file(m->RAM_file) ;
  270.             memory_symptom = "MaDstr wi->user" ;
  271.             My_free(m) ; m = NULL ;
  272.         }
  273.         /*** own window ***/
  274.         memory_symptom = "MaDstr wi" ;
  275.         Awi_delete(wi) ;
  276.         incarnation_counter-- ;
  277.     }
  278. }
  279.  
  280.  
  281. /******************************************************************
  282. */
  283.     static Awindow *MAIN_constructor(void *MIDIfile)
  284. /*
  285. * Constructor of the MAIN window (incl. all sub-windows). 
  286. *******************************************************************/
  287. {
  288. Awindow *wi ;
  289. MAIN *m ;
  290. PRINTER_INIT printer_init ;
  291. DRAWER_INIT drawer_init ;
  292. PARAMS_INIT params_init ;
  293. FILTER_INIT filter_init ;
  294. INFO_INIT info_init ;
  295. char *buffer ;
  296.  
  297.     /*** allocate and init main structure ***/
  298.     m = My_alloc(sizeof *m) ;
  299.     if (!m) return NULL ;
  300.     m->params_wi = m->info_wi = m->drawer_wi = m->printer_wi = m->filter_wi = NULL ;
  301.     m->zoom = 2 ;
  302.  
  303.     /*** if call params. contain a valid filename, take them ***/
  304.     if ( MIDIfile && (ACSblk->argc > 1) )
  305.     {
  306.         strcpy(m->pathname, (char *)MIDIfile) ;
  307.         strcpy(path, (char *)MIDIfile) ;
  308.         buffer = strrchr(path, '\\') ;
  309.         if (!buffer)
  310.         {
  311.             /*** no "\" ==> no valid path ***/
  312.             alert_str(CALL_INVALID, (char *)MIDIfile) ;
  313.             memory_symptom = "MaCstr no slash" ;
  314.             My_free(m) ; return NULL ;
  315.         }
  316.         strcpy(m->filename, buffer + 1) ;
  317.         /*** take away file name and append searching mask "*.MID" */
  318.         buffer[1] = 0 ;
  319.         strcat(path, "*.MID") ;
  320.     }
  321.     /*** else have the program user selected a MIDI file ***/
  322.     else switch ( get_file_name(m->pathname, path, m->filename, 
  323.                                 "Select MIDI file:") ) 
  324.         {
  325.         case no_file_selected: 
  326.             memory_symptom = "MaCstr no f. sel." ;
  327.             My_free(m) ; return NULL ; 
  328.         case file_select_error: 
  329.             memory_symptom = "MaCstr f.sel.err." ;
  330.             My_free(m) ; alert_str(FILE_SELECT_ERROR, "") ; return NULL ;
  331.         }
  332.     /*** load the selected file into RAM ***/
  333.     if ( load_file(m->pathname, &m->filesize, &m->RAM_file) != file_loaded )
  334.     { 
  335.         memory_symptom = "MaCstr load_file" ;
  336.         My_free(m) ; return NULL ; 
  337.     }
  338.     /*** choose icon color ***/
  339.     switch (incarnation_counter % 3)
  340.     {
  341.     case 0:
  342.         MAIN_WINDOW.iconblk = &MAIN_ICON0 ;
  343.         info_init.icon =      &INFO_ICON0 ;
  344.         filter_init.icon =    &FILTER_ICON0 ;
  345.         drawer_init.icon =    &DRAWER_ICON0 ;
  346.         params_init.icon =    &PARAMS_ICON0 ;
  347.         printer_init.icon =   &PRINTER_ICON0 ;
  348.         break ;
  349.     case 1:
  350.         MAIN_WINDOW.iconblk = &MAIN_ICON1 ;
  351.         info_init.icon =      &INFO_ICON1 ;
  352.         filter_init.icon =    &FILTER_ICON1 ;
  353.         drawer_init.icon =    &DRAWER_ICON1 ;
  354.         params_init.icon =    &PARAMS_ICON1 ;
  355.         printer_init.icon =   &PRINTER_ICON1 ;
  356.         break ;
  357.     default:
  358.         MAIN_WINDOW.iconblk = &MAIN_ICON2 ;
  359.         info_init.icon =      &INFO_ICON2 ;
  360.         filter_init.icon =    &FILTER_ICON2 ;
  361.         drawer_init.icon =    &DRAWER_ICON2 ;
  362.         params_init.icon =    &PARAMS_ICON2 ;
  363.         printer_init.icon =   &PRINTER_ICON2 ;
  364.     }
  365.     /*** enter filename into icon text and pathname into window info line ***/
  366.     MAIN_WINDOW.iconblk->monoblk.ib_ptext = m->filename ;
  367.     MAIN_WINDOW.name = m->pathname ;
  368.  
  369.     /*** create the MAIN window ***/
  370.     wi = Awi_create(&MAIN_WINDOW) ;
  371.     if (!wi) 
  372.     { 
  373.         memory_symptom = "MaCstr unload_file" ; 
  374.         unload_file(m->RAM_file) ;
  375.         memory_symptom = "MaCstr wi==NULL" ;
  376.         My_free(m) ; 
  377.         return NULL ; 
  378.     }
  379.     incarnation_counter ++ ;
  380.     wi->user = m ;
  381.     /*** set user def. object width and height ***/
  382.     (wi->work)->ob_height = (wi->work + WORK_OBJ)->ob_height = 
  383.       m->zoom * screen_out[1] ;
  384.     if (print_handle)
  385.         (wi->work)->ob_width = (wi->work + WORK_OBJ)->ob_width = m->zoom 
  386.         * ( (long)screen_out[1] * print_out[0]/print_out[1] * print_out[3]/print_out[4]) ;
  387.     else (wi->work)->ob_width = (wi->work + WORK_OBJ)->ob_width = 
  388.           (float)(m->zoom) * screen_out[1] / 1.41 ;
  389.     /*** INFO object sub-constructor ***/
  390.     info_init.filename = m->filename ;
  391.     info_init.RAM_file = m->RAM_file ;
  392.     info_init.filesize = m->filesize ;
  393.     m->info_wi = INFO_constructor(&info_init) ;
  394.     if (!m->info_wi) { MAIN_destructor(wi) ; return NULL ; }
  395.     if ( get_SMPTE(m->info_wi) ) alert_str(NO_SMPTE, "") ;
  396.     else
  397.     {
  398.         /*** FILTER object sub-constructor ***/
  399.         filter_init.filename = m->filename ;
  400.         filter_init.RAM_file = m->RAM_file ;
  401.         filter_init.filesize = m->filesize ;
  402.         filter_init.ntrks = get_number_of_tracks(m->info_wi) ;
  403.         filter_init.track_filter = on ;
  404.         filter_init.channel_filter = all_channels_on ;
  405.         m->filter_wi = FILTER_constructor(&filter_init) ;
  406.         if (!m->filter_wi) { MAIN_destructor(wi) ; return NULL ; }
  407.         /*** now total transformed size can be displayed in info window ***/
  408.         set_transformed_size( m->info_wi, get_transformed_size(m->filter_wi) ) ;    
  409.  
  410.         /*** PARAMS object sub-constructor ***/
  411.         params_init.filename = m->filename ;
  412.         params_init.path = path ;
  413.         params_init.handle = screen_handle ;
  414.         params_init.font_info = screen_font_info ;
  415.         params_init.number_fonts = number_screen_fonts ;
  416.         m->params_wi = PARAMS_constructor(¶ms_init) ;
  417.         if (!m->params_wi) { MAIN_destructor(wi) ; return NULL ; }
  418.         /*** DRAWER object sub-constructor ***/
  419.         drawer_init.filename = m->filename ;
  420.         drawer_init.handle = screen_handle ;
  421.         drawer_init.obj_wi = wi ;
  422.         drawer_init.obj = WORK_OBJ ;
  423.         drawer_init.width  = (wi->work)->ob_width  / m->zoom ;
  424.         drawer_init.height = (wi->work)->ob_height / m->zoom  ;
  425.         drawer_init.params_window = m->params_wi ;    
  426.         drawer_init.filter_window = m->filter_wi ;    
  427.         drawer_init.info_window = m->info_wi ;
  428.         m->drawer_wi = DRAWER_constructor(&drawer_init) ;
  429.         if (!m->drawer_wi) { MAIN_destructor(wi) ; return NULL ; }
  430.         /*** PRINTER object sub-constructor ***/
  431.         if ( vq_gdos() )
  432.         {
  433.             printer_init.filename = m->filename ;
  434.             printer_init.path = path ;
  435.             printer_init.screen_handle = screen_handle ;
  436.             printer_init.screen_width  = drawer_init.width ;
  437.             printer_init.screen_height = drawer_init.height ;
  438.             printer_init.print_handle = print_handle ;
  439.             printer_init.print_width  = print_out[0] + 1 ;
  440.             printer_init.print_height = print_out[1] + 1 ;
  441.             printer_init.drawer_window = m->drawer_wi ;
  442.             m->printer_wi = PRINTER_constructor(&printer_init) ;
  443.             if (!m->printer_wi) { MAIN_destructor(wi) ; return NULL ; }
  444.         }
  445.     }
  446.     /*** in any case file is no longer needed in RAM ***/
  447.     unload_file(m->RAM_file) ; m->RAM_file = NULL ;
  448.  
  449.     /*** userdef drawing routines called by AES need access to MAIN ***/ 
  450.     wi->work[WORK_OBJ].ob_spec.userblk->ub_parm = (long)m ;
  451.  
  452.     /*** return success message ***/
  453.     return wi ;
  454. }
  455.  
  456.  
  457.  
  458. /********************************************************************
  459. *
  460. *         ACS routines
  461. *
  462. ********************************************************************/
  463.  
  464.  
  465. /*******************************************************************
  466. */
  467.     static void aboutme(void) { A_dialog(&ABOUT_ME) ; }
  468. /*
  469. *   replaces the ACS default info with my own info message.
  470. *******************************************************************/
  471.  
  472. /*******************************************************************
  473. */
  474.     static void close(void)
  475. /*
  476. *   is called if the program user has selected the "exit"
  477. *   button in the menu of the desktop. After consolidation
  478. *   via alert box, clean up is performed.
  479. *******************************************************************/
  480. {
  481.     if (alert_str(QUIT_ALL, "") == 1) 
  482.     {
  483.         /*** only for debugging: ***/
  484.         /*print_operations() ;*/
  485.         /*** ACS termination procedure ***/
  486.         Aev_quit() ;
  487.     }
  488. }
  489.  
  490. /*******************************************************************
  491. */
  492.     static void terminate(void)
  493. /*
  494. *   subtitutes the ACSterm procedure. It cleans up VDI.
  495. *******************************************************************/
  496. {
  497.     /*** close virtual screen workstation ***/
  498.     if (screen_handle) 
  499.     {
  500.         if ( vq_gdos() ) vst_unload_fonts(screen_handle, 0) ;
  501.         v_clsvwk(screen_handle) ;
  502.     }
  503.     /*** close physical workstation for printer ***/
  504.     if (print_handle) 
  505.     {
  506.         if ( vq_gdos() ) vst_unload_fonts(print_handle, 0) ;    
  507.         v_clswk(print_handle) ;
  508.     }
  509. }
  510.  
  511.  
  512. /*******************************************************************
  513. */
  514.     int ACSinit(void)
  515. /*
  516. *   is called once in the start-up of ACS. See also ACS manual.
  517. *   OUTPUT: screen_handle:      virtual VDI workstation for screen
  518. *           screen_out[]:       parameters of screen workstation
  519. *           screen_font_info[]: info about GDOS fonts for screen
  520. *           print_handle:       physical VDI workstation for printer
  521. *           print_out[]:        parameters of printer workstation
  522. *           path[]:             initialized to the path where 
  523. *                               this program was started from
  524. *           ACSblk->ACSaboutme: overwritten with "aboutme"
  525. *           ACSblk->ACSclose:   overwritten with "close"
  526. *           ACSblk->ACSterm:    overwritten with "term"
  527. *           ACSblk->DEBUG_MEM:  overwritten with "debug_mem"
  528. *******************************************************************/
  529. {
  530. Awindow *wi ;
  531. unsigned int i,j,k, idbuffer ;
  532. int rgb[3] ; /* red green blue */
  533. char buffer[80] ; 
  534.  
  535.     /*** replace "about me" procedure ***/
  536.     ACSblk->ACSaboutme = aboutme ;
  537.  
  538.     /*** own click routine for "exit" button ***/
  539.     ACSblk->ACSclose = close ;
  540.  
  541.     /*** own termination procedure ***/
  542.     ACSblk->ACSterm = terminate ;
  543.  
  544.     /*** memory watcher ***/    
  545.     ACSblk->DEBUG_MEM = debug_mem ;
  546.  
  547.     /*** double click to "new" will result in a jump to "MAIN_constructor()" ***/
  548.     wi = Awi_root() ;
  549.     if (!wi) return FAIL ;
  550.     wi->service(wi, AS_NEWCALL, &MAIN_WINDOW.create) ;
  551.  
  552.     /*** open 1 virtual workstation for the screen ***/
  553.     for ( i = 0 ; i <= 8 ; i++ ) screen_in[i] = 1 ; 
  554.     screen_in[9] = 0 ; screen_in[10] = RC ; 
  555.     screen_handle = phys_handle ;  /* physical screen handle of ACS */
  556.     v_opnvwk(screen_in, &screen_handle, screen_out) ;
  557.     if (!screen_handle)    { alert_str(NO_SCREEN_WORKSTATION, "") ; return FAIL ; }
  558.  
  559.     /*** load screen fonts ***/
  560.     if ( vq_gdos() ) number_screen_fonts = screen_out[10] + vst_load_fonts(screen_handle, 0) ;
  561.     else number_screen_fonts = 1 ;
  562.     if ( number_screen_fonts > MAX_FONTS ) number_screen_fonts = MAX_FONTS ;
  563.     for ( i = 0 ; i < number_screen_fonts ; i++ )
  564.     {
  565.         idbuffer = vqt_name(screen_handle, i + 1, buffer) ;
  566.         buffer[32] = 0 ;
  567.         for ( j = 0 ; j < i ; j++ )
  568.         {
  569.             k = i ; /* destination index for new font */
  570.             if ( strcmp(buffer, screen_font_info[j].font_name) < 0 )
  571.             {
  572.                 for ( ; k > j ; k-- )
  573.                 {             
  574.                     strcpy(screen_font_info[k].font_name, screen_font_info[k-1].font_name) ;
  575.                     screen_font_info[k].font_id = screen_font_info[k-1].font_id ;
  576.                 }
  577.                 j = i ; /* break */
  578.             }
  579.         }
  580.         strcpy(screen_font_info[k].font_name, buffer) ;
  581.         screen_font_info[k].font_id = idbuffer ;
  582.     }
  583.     /*** open printer workstation and load fonts ***/
  584.     if ( vq_gdos() )
  585.     {
  586.         /*** open physical workstation for the printer ***/
  587.         print_in[0] = 21 ; /* first printer driver of assign.sys */
  588.         for ( i = 1 ; i <= 8 ; i++ ) print_in[i] = 1 ; 
  589.         print_in[9] = 0 ; print_in[10] = RC ; 
  590.         v_opnwk(print_in, &print_handle, print_out) ;
  591.         if (print_handle)
  592.         {
  593.             /*** at least 16 colors, no true color ***/
  594.             if (print_out[39] >= 16)
  595.             {
  596.                 /*** set palette to Atari standard screen palette ***/
  597.                 rgb[0] = 1000 ; rgb[1] = 1000 ; rgb[2] = 1000 ; vs_color(print_handle, 0, rgb) ;
  598.                 rgb[0] =    0 ; rgb[1] =    0 ; rgb[2] =    0 ; vs_color(print_handle, 1, rgb) ;
  599.                 rgb[0] = 1000 ; rgb[1] =    0 ; rgb[2] =    0 ; vs_color(print_handle, 2, rgb) ;
  600.                 rgb[0] =    0 ; rgb[1] = 1000 ; rgb[2] =    0 ; vs_color(print_handle, 3, rgb) ;
  601.                 rgb[0] =    0 ; rgb[1] =    0 ; rgb[2] = 1000 ; vs_color(print_handle, 4, rgb) ;
  602.                 rgb[0] =    0 ; rgb[1] = 1000 ; rgb[2] = 1000 ; vs_color(print_handle, 5, rgb) ;
  603.                 rgb[0] = 1000 ; rgb[1] = 1000 ; rgb[2] =    0 ; vs_color(print_handle, 6, rgb) ;
  604.                 rgb[0] = 1000 ; rgb[1] =    0 ; rgb[2] = 1000 ; vs_color(print_handle, 7, rgb) ;
  605.                 rgb[0] =  800 ; rgb[1] =  800 ; rgb[2] =  800 ; vs_color(print_handle, 8, rgb) ;
  606.                 rgb[0] =  500 ; rgb[1] =  500 ; rgb[2] =  500 ; vs_color(print_handle, 9, rgb) ;
  607.                 rgb[0] =  500 ; rgb[1] =    0 ; rgb[2] =    0 ; vs_color(print_handle, 10, rgb) ;
  608.                 rgb[0] =    0 ; rgb[1] =  500 ; rgb[2] =    0 ; vs_color(print_handle, 11, rgb) ;
  609.                 rgb[0] =    0 ; rgb[1] =    0 ; rgb[2] =  500 ; vs_color(print_handle, 12, rgb) ;
  610.                 rgb[0] =    0 ; rgb[1] =  500 ; rgb[2] =  500 ; vs_color(print_handle, 13, rgb) ;
  611.                 rgb[0] =  500 ; rgb[1] =  500 ; rgb[2] =    0 ; vs_color(print_handle, 14, rgb) ;
  612.                 rgb[0] =  500 ; rgb[1] =    0 ; rgb[2] =  500 ; vs_color(print_handle, 15, rgb) ;
  613.             }
  614.             number_print_fonts = print_out[10] + vst_load_fonts(print_handle, 0) ;
  615.         }
  616.         else alert_str(PRINTING_NOT_POSSIBLE, "") ;
  617.     }
  618.     else alert_str( NO_GDOS, "") ;
  619.  
  620.     /*** get actual path for file searching ***/
  621.     strcpy(path, apppath) ;
  622.     strcat(path, "*.MID") ;     /* append mask for searching */
  623.     
  624.     /*** init timer management ***/
  625.     init_time() ;
  626.     
  627.     /*** call already now if a file name has been given ***/
  628.     for (i = 1 ; i < ACSblk->argc ; i ++) MAIN_constructor(ACSblk->argv[i]) ;
  629.     return OK ;
  630. }
  631.  
  632.  
  633. /*******************************************************************
  634. */
  635.     int ACSinit0(void)
  636. /*
  637. *   "ACSinit0" is called once very early in the start-up of ACS. 
  638. *   See also ACS manual.
  639. *
  640. * INPUT:   _01_BACKGND_?:       my own background objects for the 
  641. *                               ACS desktop
  642. *          DESK_MENU:           my own menu line 
  643. *          NEW/TRASH:           my own icons
  644. *          MAIN_window.create   create routine of the main window
  645. *          DESKTOP:             desktop of ACS
  646. *          multitask            indicates if multitasking is active
  647. *          application          indicates programm or accessory
  648. * OUTPUT:  ACS default desktop objects replaced by own objects
  649. *******************************************************************/
  650. {
  651.     /*** replace desktop background object ***/
  652.     if ( multitask || !application )
  653.     {
  654.         _01_BACKGND_2.ob_width = _01_BACKGND_16.ob_width = desk.w/2 ;
  655.         _01_BACKGND_2.ob_height = _01_BACKGND_16.ob_height = desk.h/2 ;
  656.     }
  657.     else
  658.     {
  659.         _01_BACKGND_2.ob_width = _01_BACKGND_16.ob_width = desk.w ;
  660.         _01_BACKGND_2.ob_height = _01_BACKGND_16.ob_height = desk.h ;
  661.     }
  662.     if (ncolors >= 16) DESKTOP.service(NULL, AS_BACKOBJECT, &_01_BACKGND_16) ;
  663.     else DESKTOP.service(NULL, AS_BACKOBJECT, &_01_BACKGND_2) ;
  664.  
  665.     /*** replace desktop menu ***/
  666.     DESKTOP.menu = &DESK_MENU ;
  667.  
  668.     /*** adapt menu entries to propgram type ***/
  669.     if (application && !multitask) DESKTOP.menu[ABOUTME].ob_flags |= HIDETREE ; 
  670.     if (!application) DESKTOP.menu[_EXIT].ob_state |= DISABLED ; 
  671.  
  672.     /*** replace "trash" and "new" icon ***/
  673.     DESKTOP.service(NULL, AS_ICONNEW,   &NEW  ) ;
  674.     DESKTOP.service(NULL, AS_ICONTRASH, &TRASH) ;
  675.  
  676.     /*** replace window title ***/
  677.     DESKTOP.name = " Mad Harry's Midi File Printer " ;
  678.  
  679.     /*** always OK ***/
  680.     return OK ;
  681. }
  682.  
  683.