home *** CD-ROM | disk | FTP | other *** search
/ Frozen Fish 1: Amiga / FrozenFish-Apr94.iso / bbs / alib / d9xx / d952 / machv.lha / MachV / programmer.lha / PrintMacros / PrintMacros.c < prev    next >
C/C++ Source or Header  |  1993-09-20  |  17KB  |  630 lines

  1. #define PRTMAC_C
  2.  
  3. /* PrintMacros - Version 1.0 07-10-93    TAB STOPS SET TO 4!
  4.    Copywrite 1993 by Brian Moats
  5.  
  6.    This program will print MachV macros to the printer, a file, or a window.
  7.    It requires MachV 5.0 or later to be running.
  8.  
  9.    PrintMacros is called from SetMachV when you click on 'Print Macros'. The
  10.    configuration that is current at that time is the one whose macros will be
  11.    printed. It may also be called from the shell with one argument - the name
  12.    of the desired configuration. If no name is supplied, the current
  13.    configuration will be printed.
  14.  
  15.    You may also create a macro that will execute this program. Example:
  16.  
  17.    Exe_Cmd"PrintMacros \"GNU Emacs#?\""
  18.  
  19.    This program may also serve as an example of how to interact with MachV.
  20.    It is not an elegant example of coding, however ;-).
  21.  
  22.    If you have the appropriate catalog, PrintMacros will adapt to that
  23.    language. deutsch and français are provided.
  24.  
  25.    Because MachV is locked by ObtainSemaphore() while printing, MachV can
  26.    not do anything. This may be inconvenient, but it is proper.
  27.  
  28.  
  29.    sc PrintMacros
  30.    slink lib:cback.o PrintMacros.o lib lib:sc.lib lib:debug.lib lib:amiga.lib
  31.  
  32.    or to make smaller:
  33.  
  34.    slink lib:cback.o PrintMacros.o sprintf.o lib lib:sc.lib lib:debug.lib \
  35.          lib:amiga.lib
  36.    
  37.        (requires sprintf.a)
  38.  
  39. */
  40.  
  41. #include <string.h>
  42. #include <stdio.h>
  43. #include <proto/asl.h>
  44. #include <proto/dos.h>
  45. #include <proto/exec.h>
  46. #include <proto/gadtools.h>
  47. #include <proto/graphics.h>
  48. #include <proto/intuition.h>
  49. #include <proto/utility.h>
  50. #include <clib/keymap_protos.h>
  51. #include <clib/locale_protos.h>
  52. #include <exec/execbase.h>
  53. #include <exec/types.h>
  54. #include <exec/memory.h>
  55. #include <exec/ports.h>
  56. #include <graphics/gfxbase.h>
  57. #include <intuition/intuition.h>
  58. #include <intuition/intuitionbase.h>
  59. #include <libraries/gadtools.h>
  60.  
  61. #define STRINGARRAY
  62.  
  63. #include "prtstr.h" /* created by catcomp */
  64. #include "m43:headers/mach.h"
  65. #include "m43:headers/machlib.h"
  66. #include "m43:headers/machlib_protos.h"
  67. #include "m43:headers/machlib_pragmas.h"
  68.  
  69. #define WIN_WIDTH    150
  70. #define WIN_HEIGHT    76
  71.  
  72. #define WIN_FLAGS  WFLG_ACTIVATE | WFLG_SMART_REFRESH | WFLG_CLOSEGADGET | \
  73.                    WFLG_NOCAREREFRESH | WFLG_DEPTHGADGET | WFLG_DRAGBAR
  74.     
  75. #define IDCMP_FLAGS IDCMP_CLOSEWINDOW | IDCMP_GADGETUP | IDCMP_REFRESHWINDOW
  76.     
  77. #define WHERE_GID   100
  78. #define GO_GID      101
  79. #define ABORT_GID   102
  80.  
  81. #define PRINT_TO_CONSOLE     0
  82. #define PRINT_TO_PRINTER     1
  83. #define PRINT_TO_FILE         2    
  84.  
  85. /* ============== Local Protos ============== */
  86.  
  87. static void handle_msg(void);
  88. static BOOL main_window_open(void);
  89. static void main_window_close(void);
  90. static void set_language(void);
  91. static void print_macros(void);
  92. static void get_keytext(UWORD key,UWORD qual);
  93. static BOOL XLateKeyQual(UWORD code,UWORD qual,UBYTE *buf);
  94. static BOOL FileByRequest(void);
  95. static void FreeFileRequestStruct(void);
  96.  
  97. static void writemacro(void);
  98. static void writestr(char *s);
  99. static void writehdr(void);
  100. static void writedash(void);
  101. static void writepadded(char *str,long max);
  102. static void pause(void);
  103. static void getquals(void);
  104.  
  105.  
  106. /* ============= Globals ============== */
  107.  
  108. struct MachLibrary *MachBase;
  109. struct IntuitionBase *IntuitionBase;
  110. struct GfxBase *GfxBase;
  111. struct Library *GadToolsBase, *LocaleBase, *KeymapBase, *AslBase;
  112. APTR Catalog;
  113.  
  114. /* detach stuff */
  115.  
  116. long __stack = 4000;
  117. long __priority = 0;
  118. long __BackGroundIO = 1;
  119. char *__procname = "PRINTMACROS";
  120.  
  121. extern BPTR _Backstdout;   /* file handle we will write to with */
  122.  
  123. /* ============== Locals ============== */
  124.  
  125. static struct Window *mainw;
  126.  
  127. static struct TextAttr Topaz80 = {(STRPTR)"topaz.font",8,0,FPF_ROMFONT};
  128. static struct VisualInfo  *VI; 
  129.  
  130. static char *where_labels[] = {NULL,NULL,NULL,NULL};
  131.  
  132. static struct Gadget *print_glist;
  133.  
  134. static WORD wle,conh,conw;
  135. static WORD where_to;
  136. static BOOL print_done,wb_to_back;
  137. static LONG maxlines,maxconsolelines,linecnt;
  138.  
  139. static BPTR fh;
  140. static char printdirname[80],printfilename[40];
  141.  
  142. static char blanks[43] = "                                          ";
  143. static char pressreturn[] = "Press Return";
  144.  
  145. static char curname[16]; /* name of macro currently being printed */
  146.  
  147. static char constr[50] = "Con:0/0/640/200/Macros/CLOSE";
  148.  
  149. static char qualtext[16],keytext[10];
  150.  
  151. static struct MacroObject *mo; /* macro currently being printed */
  152. static struct MachCfg  *cfg;
  153.  
  154. static ULONG toppix;
  155.  
  156.  
  157. main(int argc, char **argv)
  158. {
  159.     IntuitionBase = (struct IntuitionBase *) OpenLibrary("intuition.library",37L);
  160.     GfxBase    = (struct GfxBase *) OpenLibrary("graphics.library",37L);
  161.     GadToolsBase = OpenLibrary("gadtools.library",37L);
  162.     KeymapBase        = (struct Library*)OpenLibrary("keymap.library",0L);
  163.     MachBase = (struct MachLibrary*)OpenLibrary("mach.library",37L);
  164.  
  165.     if (cfg = MachBase->ml_CurConfig) { /* then MachV is running */
  166.         set_language();
  167.         where_to = PRINT_TO_CONSOLE;
  168.         if (argc > 1) {
  169.             argv++;
  170.             cfg = FindConfigByName(*argv);
  171.         }
  172.         if (cfg) {
  173.             if (main_window_open()) {
  174.                 while (mainw) {
  175.                     Wait(1L << mainw->UserPort->mp_SigBit);
  176.                     handle_msg();
  177.                 }
  178.             }
  179.         }
  180.         else
  181.             Write(_Backstdout,"Can't find configuration!\n",26L);
  182.         CloseLibrary((struct Library*)MachBase);
  183.     }
  184.     else
  185.         Write(_Backstdout,"MachV must be active first!\n",30L);
  186.     if (wb_to_back)
  187.         WBenchToBack();
  188.     if (IntuitionBase)
  189.         CloseLibrary((struct Library*)IntuitionBase);
  190.     if (GfxBase)
  191.         CloseLibrary((struct Library*)GfxBase);
  192.     if (GadToolsBase)
  193.         CloseLibrary(GadToolsBase);
  194.     if (KeymapBase)
  195.         CloseLibrary(KeymapBase);
  196. }
  197.  
  198. static void print_macros(void)
  199. {
  200.     UBYTE            fullpath[160];
  201.     ULONG             match_type;
  202.  
  203.     switch (where_to) {
  204.     case PRINT_TO_CONSOLE:
  205.         sprintf(constr,"Con:0/0/640/%ld/Macros/CLOSE",conh);
  206.         fh = Open((STRPTR)constr,MODE_OLDFILE);
  207.         maxlines = maxconsolelines;
  208.         break;
  209.     case PRINT_TO_PRINTER:
  210.         fh = Open((STRPTR)"prt:",MODE_OLDFILE);
  211.         maxlines = 99999;
  212.         break;
  213.     case PRINT_TO_FILE:
  214.         if (AslBase = OpenLibrary((UBYTE*)"asl.library",37L)) {
  215.             if (FileByRequest()) {
  216.                 strcpy((char*)fullpath,printdirname);
  217.                 AddPart(fullpath,(UBYTE*)printfilename,160);
  218.                 fh = Open((STRPTR)fullpath,MODE_NEWFILE);
  219.                 FreeFileRequestStruct();
  220.             }
  221.             CloseLibrary(AslBase);
  222.         }
  223.         maxlines = 99999;
  224.         break;
  225.     }
  226.     print_done = 0;
  227.     linecnt = 0;
  228.     if (fh) {
  229.         writestr(cfg->mc_Title);
  230.         writehdr();
  231.         writedash();
  232.         ObtainSemaphore(&MachBase->ml_BaseSemaphore);
  233.         while (!print_done) {
  234.             match_type = MT_WILDCARDS; /* find all macros */
  235.             while (mo = FindByName(cfg,"#?",match_type)) {
  236.                 match_type |= MT_MATCH_NEXT;     /* keep going */
  237.                 writemacro(); /* write to printer, file or window */
  238.                 if (print_done) /* writestr() can set this */
  239.                     break;
  240.                 handle_msg();  /* check for abort gadget hit */
  241.             }
  242.             if (mo == NULL) /* did all, now pause */
  243.                 pause();
  244.             break;
  245.         }
  246.         ReleaseSemaphore(&MachBase->ml_BaseSemaphore);
  247.         Close(fh);
  248.         fh = NULL;
  249.     }
  250. }
  251.  
  252. static void handle_msg(void)
  253. {
  254.     struct IntuiMessage *imsg;
  255.     struct Gadget *gadget;
  256.     ULONG iclass;
  257.     WORD icode;
  258.  
  259.     while (mainw && (imsg = GT_GetIMsg(mainw->UserPort))) {
  260.         iclass = imsg->Class;
  261.         icode = imsg->Code;
  262.         gadget = (struct Gadget *) imsg->IAddress;
  263.         GT_ReplyIMsg(imsg);
  264.         if (iclass == IDCMP_GADGETUP) {
  265.             switch (gadget->GadgetID) {
  266.             case WHERE_GID:
  267.                 where_to = icode;
  268.                 break;
  269.             case GO_GID:
  270.                 if (fh == NULL) /* not already printing? */
  271.                     print_macros();
  272.                 break;
  273.             case ABORT_GID:
  274.                 print_done = 1;
  275.                 break;
  276.             }
  277.         }
  278.         if (iclass == IDCMP_CLOSEWINDOW)
  279.             main_window_close();
  280.     }
  281. }
  282.  
  283. static BOOL main_window_open(void)
  284. {
  285.     struct Screen *public_screen;
  286.     struct Gadget *gad;
  287.     struct NewGadget ng;
  288.     int i,w,width;
  289.  
  290.     where_labels[0] = AppStrings[MSG_DEST_WINDOW_GAD].as_Str;
  291.     where_labels[1] = AppStrings[MSG_DEST_PRINTER_GAD].as_Str;
  292.     where_labels[2] = AppStrings[MSG_DEST_FILE_GAD].as_Str;
  293.  
  294.     width = 0; /* get max width for cycle gadget */
  295.     for (i=0;i<3;i++)
  296.         if ((w = strlen(where_labels[i])) > width)
  297.             width = w;
  298.  
  299.     if ((public_screen = LockPubScreen(NULL)) != NULL) {
  300.         VI = GetVisualInfoA(public_screen,TAG_END);
  301.         toppix = public_screen->FirstWindow->BorderTop + 1;
  302.         wle = ((GfxBase->NormalDisplayColumns >> 1) - public_screen->LeftEdge - (WIN_WIDTH / 2));
  303.         conh = GfxBase->NormalDisplayRows;
  304.         conw = GfxBase->NormalDisplayColumns;
  305.         if (public_screen->ViewPort.Modes & LACE)
  306.             conh <<= 1;
  307.         maxconsolelines = (conh - toppix) / public_screen->RastPort.TxHeight - 4;
  308.         wb_to_back = public_screen != IntuitionBase->FirstScreen;
  309.         UnlockPubScreen(NULL,public_screen);
  310.     }
  311.     ng.ng_VisualInfo = VI;
  312.     ng.ng_TextAttr = &Topaz80;
  313.     ng.ng_Height = 12;
  314.     ng.ng_Flags = PLACETEXT_IN;
  315.     
  316.     gad = CreateContext(&print_glist);
  317.     
  318.     /* =============== CYCLE_KIND ================= */
  319.     ng.ng_GadgetText = NULL;
  320.     ng.ng_Width = width * 8 + 32;
  321.     ng.ng_LeftEdge = (WIN_WIDTH - ng.ng_Width) / 2;
  322.     ng.ng_TopEdge = toppix+2;
  323.     ng.ng_GadgetID = WHERE_GID;
  324.     gad = CreateGadget(CYCLE_KIND, gad, &ng, GTCY_Labels, (ULONG)where_labels, 
  325.                         GTCY_Active, 0,TAG_DONE);
  326.     
  327.     /* =============== Go BUTTON_KIND ================= */
  328.     ng.ng_GadgetText = AppStrings[MSG_GO_GAD].as_Str;
  329.     ng.ng_Width = strlen((char*)ng.ng_GadgetText)*8 + 8;
  330.     ng.ng_LeftEdge = (WIN_WIDTH - ng.ng_Width) / 2;
  331.     ng.ng_TopEdge = toppix+24;
  332.     ng.ng_GadgetID = GO_GID;
  333.     gad = CreateGadget(BUTTON_KIND, gad, &ng, TAG_DONE);
  334.     
  335.     /* =============== Abort BUTTON_KIND ================= */
  336.     ng.ng_TopEdge = toppix + 46;
  337.     ng.ng_GadgetText = AppStrings[MSG_ABORT_PRINT_GAD].as_Str;
  338.     ng.ng_Width = strlen(ng.ng_GadgetText)*8 + 8;
  339.     ng.ng_LeftEdge = (WIN_WIDTH - ng.ng_Width) / 2;
  340.     ng.ng_GadgetID = ABORT_GID;
  341.     gad = CreateGadget(BUTTON_KIND, gad, &ng, TAG_DONE);
  342.  
  343.     if (gad) {
  344.         if (mainw = OpenWindowTags(NULL, WA_Left, wle,
  345.                                    WA_Top,30,
  346.                                    WA_Width, WIN_WIDTH,
  347.                                    WA_Height, WIN_HEIGHT,
  348.                                    WA_IDCMP,IDCMP_FLAGS,
  349.                                    WA_Flags,WIN_FLAGS,
  350.                                    WA_Title,(ULONG)AppStrings[MSG_TITLE_STR].as_Str,
  351.                                    WA_AutoAdjust,TRUE,TAG_DONE)) {
  352.             AddGList(mainw, print_glist, -1, -1, NULL);
  353.             RefreshGList(print_glist, mainw, NULL, -1);
  354.             GT_RefreshWindow(mainw, NULL);
  355.             WBenchToFront();
  356.         }
  357.         else {
  358.             main_window_close(); /* frees glist */
  359.         }
  360.     }
  361.     return((BOOL)(gad != NULL));
  362. }
  363.  
  364. static void main_window_close(void)
  365. {
  366.     print_done = 1;
  367.     if (mainw)
  368.         CloseWindow(mainw);
  369.     mainw = NULL;
  370.     if (print_glist)
  371.         FreeGadgets(print_glist);
  372.     if (VI)
  373.         FreeVisualInfo(VI);
  374. }
  375.  
  376. /*=================================
  377.   Set AppStrings if foreign tongue.
  378.   =================================*/
  379.  
  380. static void set_language(void)
  381. {
  382.     int i;
  383.  
  384.     if (LocaleBase = OpenLibrary("locale.library",38)) {
  385.         Catalog = OpenCatalog(NULL,"machv/printmacros.catalog",TAG_DONE);
  386.         if (Catalog) {
  387.             for (i=0;i < LAST_LINE_OF_TEXT;i++) {
  388.                 AppStrings[i].as_Str = GetCatalogStr(Catalog,i,AppStrings[i].as_Str);
  389.             }
  390.         }
  391.     }
  392. }
  393.  
  394. /*===========================================
  395.   write: keytext  qualtext  curname  |  macro
  396.          ----------------------------+-------
  397.   ===========================================*/
  398. static void writemacro(void)
  399. {
  400.     char *mac;
  401.     int len;
  402.  
  403.     mac = mo->mo_Macro;
  404.     len = mo->mo_Size;
  405.     strcpy(curname,mo->mo_Name);
  406.     get_keytext(mo->mo_Code,mo->mo_Qual);
  407.     if (mo->mo_Code != UNKEYED) /* no qualifiers with unkeyed macros */
  408.         getquals();
  409.     while (len > 0) { /* do 42 chars of macro on each line */
  410.         writepadded((char*)keytext,8);
  411.         writepadded(qualtext,9);
  412.         writepadded(curname,14 );
  413.         writestr(" | ");
  414.         writepadded(mac,42 );
  415.         writestr("\n");
  416.         linecnt++;
  417.         *keytext = '\0'; /* don't want key qual and name on extra lines */
  418.         *qualtext = '\0';
  419.         *curname = '\0';
  420.         mac += 42;
  421.         len -= 42;
  422.     }
  423.     if (linecnt > maxlines) { /* this can only be true if output to window */
  424.         pause(); /* shows 'Press Return' and waits for input */
  425.         linecnt = 0;
  426.         writehdr();
  427.     }
  428.     writedash();
  429. }
  430.  
  431. static void writestr(char *s)
  432. {
  433.     if (!print_done)
  434.         if (FPuts(fh,s) == -1)
  435.             print_done = 1;
  436. }
  437.  
  438. static void writehdr(void)
  439. {
  440.     writestr("\nKey   Qualifier    Name           Macro\n");
  441.     linecnt++;
  442. }
  443.  
  444. static void writedash(void)
  445. {
  446.     writestr("--------------------------------+-------------------------------------------\n" );
  447.     linecnt++;
  448. }
  449.  
  450. /*=========================================================
  451.   Write a string. If length less than max, pad with blanks.
  452.   If more than max, write only max chars. 
  453.   =========================================================*/
  454. static void writepadded(char *str,long max)
  455. {
  456.     long len;
  457.     char savechr;
  458.  
  459.     len = strlen(str);
  460.     if (len > max) {
  461.         savechr = str[max];
  462.         str[max] = '\0'; /* writestr needs null terminated string */
  463.     }
  464.     writestr(str);
  465.     if (len > max) {
  466.         str[max] = savechr;
  467.     }
  468.     if ((len = max-len) > 0) {
  469.         blanks[len] = '\0';
  470.         writestr(blanks);
  471.         blanks[len] = ' ';
  472.     }
  473. }
  474.  
  475. /*=================================================================
  476.   Print 'Press Return' and wait for input only if output to window.
  477.   =================================================================*/
  478. static void pause(void)
  479. {
  480.     if (where_to == PRINT_TO_CONSOLE) {
  481.         writestr(pressreturn);
  482.         Flush(fh);
  483.         if (FGetC(fh) == -1) { /* close gadget or ctrl-c */
  484.             print_done = 1;
  485.         }
  486.     }
  487. }
  488.  
  489. /*=====================================================================
  490.   Set qualtext to the letters C A S L R for the appropriate qualifiers.
  491.   =====================================================================*/
  492.  
  493. static struct table {WORD  qual;
  494.                      char let;} qualTab[] = {
  495.                     IEQUALIFIER_CONTROL,'C',
  496.                     IEQUALIFIER_LALT | IEQUALIFIER_RALT,'A',
  497.                     IEQUALIFIER_LCOMMAND,'L',
  498.                     IEQUALIFIER_RCOMMAND,'R',
  499.                     IEQUALIFIER_LSHIFT | IEQUALIFIER_RSHIFT,'S'
  500. };
  501.  
  502. static void getquals(void)
  503. {
  504.     WORD i, idx;
  505.     
  506.     i = 0;
  507.     for (idx=0;idx<5;idx++) {
  508.         if (mo->mo_Qual & qualTab[idx].qual) {
  509.             qualtext[i++] = qualTab[idx].let;
  510.             qualtext[i++] = '+';
  511.         }
  512.     }
  513.     if (i > 0)
  514.         qualtext[--i] = 0;
  515. }
  516.  
  517. /*====================================
  518.   Set keytext for the appropriate key.
  519.   ====================================*/
  520.  
  521. #define N0         0x0f
  522. #define N1         0x1d
  523. #define N2         0x1e
  524. #define N3         0x1f
  525. #define N4         0x2d
  526. #define N5         0x2e
  527. #define N6         0x2f
  528. #define N7         0x3d
  529. #define N8         0x3e
  530. #define N9         0x3f
  531. #define NDP         0x3c
  532.  
  533. static short nptab[] = {
  534.     N7, N8, N9, N4, N5, N6,
  535.     N1, N2, N3, N0, NDP,
  536.     0};
  537.  
  538. /* these are in keycode order */
  539. static char *speckeys[] = {"SPACE ", "BACKSP", "TAB   ", "ENTER ", "RETURN",
  540.                            "ESC   ", "DEL   ", "", "", "", "KP -  ", "",
  541.                            "UP    ", "DOWN  ", "RIGHT ", "LEFT  ", "F1    ",
  542.                            "F2    ", "F3    ", "F4    ", "F5    ", "F6    ",
  543.                            "F7    ", "F8    ", "F9    ", "F10   ", "KP (  ",
  544.                            "KP )  ", "KP /  ", "KP *  ", "KP +  ", "HELP  ",
  545.                            "", "", "", "", "", "", "", "",
  546.                            "L Butn", "R Butn", "M Butn"
  547. };
  548.  
  549. static void get_keytext(UWORD key,UWORD qual)
  550. {
  551.     WORD i;
  552.     
  553.     /* if special key */
  554.     if ((key >= 0x40) && (key < UNKEYED)) {  
  555.         i = key - 0x40;
  556.         if ((i >= (sizeof(speckeys)/4)) || (*speckeys[i] == '\0')) {
  557.             sprintf(keytext,"0x%02lx",(ULONG)key);
  558.         }
  559.         else
  560.             strcpy((char *)keytext,speckeys[i]);
  561.     }
  562.     else {    /* 1st check for numeric pad keys */
  563.         i = 0;
  564.         if (key < 128) {
  565.             qual &= IEQUALIFIER_RSHIFT | IEQUALIFIER_LSHIFT;
  566.             while (nptab[i] && (key != nptab[i]))
  567.                 i++;
  568.             if (nptab[i]) {
  569.                 strcpy((char*)keytext,"KP ");
  570.                 qual |= IEQUALIFIER_NUMERICPAD;
  571.                 i = 3;
  572.             }
  573.             else {
  574.                 strcpy((char*)keytext,"  ");
  575.                 i = 2;
  576.             }
  577.             if (!XLateKeyQual(key,qual,&keytext[i])) {
  578.                 sprintf(keytext,"0x%02x",(UWORD)key);
  579.                 i = 3;
  580.             }
  581.             i++;
  582.             while (i < 6)
  583.                 keytext[i++] = ' ';
  584.             keytext[i] = '\0';
  585.         }
  586.         else
  587.             strcpy((char*)keytext,"NO KEY");
  588.     }
  589. }
  590.  
  591. /*=========================================================
  592.   Translate a key code and qualifier to ascii, if possible.
  593.   =========================================================*/
  594.  
  595. static BOOL XLateKeyQual(UWORD code,UWORD qual,UBYTE *buf)
  596. {
  597.     struct InputEvent ev;
  598.  
  599.     memset(&ev,0,sizeof(struct InputEvent));
  600.     ev.ie_Class = IECLASS_RAWKEY;
  601.     ev.ie_Code = code;
  602.     ev.ie_Qualifier = qual;
  603.     return((BOOL)(MapRawKey(&ev,buf,1L,NULL) != -1));
  604. }
  605.  
  606. /*============================
  607.   Simple file request routine.
  608.   ============================*/
  609.  
  610. static struct FileRequester *file_requester;
  611.  
  612. static BOOL FileByRequest(void)
  613. {
  614.   if (file_requester = (APTR)AllocAslRequest(ASL_FileRequest,TAG_DONE)) {
  615.     if (AslRequest(file_requester,TAG_DONE)) {
  616.       strcpy(printdirname,(char*)file_requester->fr_Drawer);
  617.       strcpy(printfilename,(char*)file_requester->fr_File);
  618.       return(TRUE);
  619.     }
  620.   }
  621.   return(FALSE);
  622. }
  623.  
  624. static void FreeFileRequestStruct(void)
  625. {
  626.   if (file_requester != NULL)
  627.     FreeAslRequest(file_requester);
  628. }
  629.  
  630.