home *** CD-ROM | disk | FTP | other *** search
/ Club Amiga de Montreal - CAM / CAM_CD_1.iso / files / 633.lha / WB_Printer / WBPrinter.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-04-25  |  32.6 KB  |  1,096 lines

  1. /*
  2.  * WBPrinter - Put a printer icon on the workbench screen
  3.  * 
  4.  *
  5.  * Copyright (c) 1992, Mike Ruble
  6.  *
  7.  * Permission is hereby granted to distribute this program for any purposes
  8.  * whatsoever, so long as this notice, including the above copyright, is
  9.  * included with the distribution.
  10.  *
  11.  * 04/25/92 Written by Mike Ruble using SAS (Lattice) C 5.10b
  12.  *
  13.  */
  14.  
  15.  
  16. #include "WBPrinter.h"
  17.  
  18.  
  19. /********** Code begins **********/
  20. void main(int argc, char *argv)
  21. {
  22.  
  23. /* First make sure we are running from Workbench */
  24.    if(argc)
  25.       exit(0);
  26.  
  27. /* Then see if WBPrinter is already running */
  28.    if(FindPort("WBPrinter"))
  29.       exit(0);
  30.  
  31.  
  32. /* Close any stdio files that might be open */
  33.    if(stdin) fclose(stdin);
  34.    if(stderr) fclose(stderr);
  35.  
  36.    SetUp();
  37.    StartPrintTask();
  38.    Do_MainFunc();
  39.    done(0);
  40. }
  41.  
  42.  
  43. void Do_MainFunc(void)
  44. {
  45.    BPTR                  infile,
  46.                          outfile,
  47.                          oldcd;
  48.    char                 *Copybuffer;
  49.    struct FileNode      *namenode;
  50.    struct AppMessage    *amsg;
  51.    struct WBArg         *argptr;
  52.    struct FileRequester *FileReq;
  53.    int                   bytesread;
  54.    int                   quit;
  55.    int                   i;
  56.  
  57.    quit = 0;
  58.    filecount = 1;
  59.  
  60.    while(!quit)
  61.    {
  62.       WaitPort(AppPort);
  63.       while ((amsg = (struct AppMessage *)GetMsg(AppPort)) != NULL)
  64.       {
  65.          if (amsg->am_NumArgs == 0)
  66.          {
  67.             ObtainSemaphore(print_q_semaphore);
  68.             quit = Do_AppWindow();
  69.             ReleaseSemaphore(print_q_semaphore);
  70.             break;
  71.          }
  72.          argptr = amsg->am_ArgList;
  73.          if(!spooldir)
  74.          {
  75.             FileReq = AllocAslRequestTags(ASL_FileRequest,
  76.                               ASL_Hail, &"CHOOSE SPOOL DIRECTORY",
  77.                               ASL_Window, Wnd,
  78.                               ASL_Dir, spooldir,
  79.                               ASL_ExtFlags1, FIL1F_NOFILES,
  80.                               TAG_DONE);
  81.  
  82.             if(FileReq)
  83.             {
  84.                if(AslRequest(FileReq, NULL))
  85.                {
  86.                   spooldir = AllocMem(strlen(((struct FileRequester *)FileReq)->rf_Dir) + 1, MEMORY_TYPE);
  87.                   if(!spooldir)
  88.                      break;
  89.                   strcpy(spooldir,
  90.                       ((struct FileRequester *)FileReq)->rf_Dir);
  91.                };
  92.                FreeAslRequest(FileReq);
  93.                FileReq = NULL;
  94.             };
  95.          };
  96.          for (i = 0; i < amsg->am_NumArgs; i++)
  97.          {
  98.             if (*(argptr->wa_Name))
  99.             {
  100.                if((namenode = 
  101.                      (struct FileNode *)AllocMem(sizeof(struct FileNode),
  102.                      MEMORY_TYPE)) == NULL)
  103.                {
  104.                   break;
  105.                };
  106.                if((namenode->nn_Node.ln_Name =
  107.                      (char *)AllocMem(strlen(argptr->wa_Name)+1,
  108.                      MEMORY_TYPE)) == NULL)
  109.                {
  110.                   break;
  111.                };
  112.                namenode->nn_Node.ln_Type = PRINT_FILE;
  113.                strcpy(namenode->nn_Node.ln_Name, argptr->wa_Name);
  114.                sprintf(Name_Buffer, "%s%ld", FilePrefix, filecount);
  115.                if((namenode->nn_SpooledName =
  116.                      (char *)AllocMem(strlen(Name_Buffer)+1,
  117.                      MEMORY_TYPE)) == NULL)
  118.                {
  119.                   break;
  120.                };
  121.                strcpy(namenode->nn_SpooledName, Name_Buffer);
  122.                strcpy(Name_Buffer, spooldir);
  123.                AddPart(Name_Buffer, namenode->nn_SpooledName, 255);
  124.  
  125.                oldcd = CurrentDir(argptr->wa_Lock);
  126.                infile = Open(argptr->wa_Name, MODE_OLDFILE);
  127.                if(infile == NULL)
  128.                {
  129.                   break;
  130.                };
  131.                outfile = Open(Name_Buffer, MODE_NEWFILE);
  132.                if(outfile == NULL)
  133.                {
  134.                   Close(infile);
  135.                   break;
  136.                };
  137.                if((Copybuffer =
  138.                     (char *)AllocMem(8192, MEMORY_TYPE)) == NULL)
  139.                {
  140.                   Close(infile);
  141.                   Close(outfile);
  142.                   break;
  143.                };
  144.                do
  145.                {
  146.                   bytesread = Read(infile, Copybuffer, 8192);
  147.                   Write(outfile, Copybuffer, bytesread);
  148.                }
  149.                while(bytesread == 8192);
  150.                Close(infile);
  151.                Close(outfile);
  152.                FreeMem(Copybuffer, 8192);
  153.                CurrentDir(oldcd);
  154.  
  155.                ObtainSemaphore(print_q_semaphore);
  156.                AddTail(Print_Q, (struct Node *)namenode);
  157.                ReleaseSemaphore(print_q_semaphore);
  158.                filecount ++;
  159.             }
  160.             argptr++;
  161.          }
  162.          Tell_Print_Task(PRINTS_READY);
  163.          ReplyMsg((struct Message *) amsg);
  164.       }
  165.    }
  166.    WaitPort(start_msg->msg.mn_ReplyPort);
  167.    GetMsg(start_msg->msg.mn_ReplyPort);
  168.    DeletePort(start_msg->msg.mn_ReplyPort);
  169.    FreeMem(start_msg, sizeof(struct ProcMsg));
  170.    Clear_Print_Q();
  171. }
  172.  
  173.  
  174. /*
  175.  * SetUp - Allocate memory and open Libraries
  176.  */
  177. void SetUp(void)
  178. {
  179.    struct Task  *Me;
  180.    char         *tooltype;
  181.    LONG          icon_left,
  182.                  icon_top;
  183.  
  184.  
  185.    window_top = window_left = 0;
  186.  
  187. /* Initialize print List */
  188.    Print_Q =
  189.          (struct List *)AllocMem(sizeof(struct List),
  190.                                  MEMORY_TYPE);
  191.    if(!Print_Q)
  192.       done(20);
  193.    NewList(Print_Q);
  194.  
  195. /* Initialize Semaphore */
  196.    print_q_semaphore =
  197.          (struct SignalSemaphore *)AllocMem(sizeof(struct SignalSemaphore),
  198.                                             MEMORY_TYPE);
  199.    if(!print_q_semaphore)
  200.       done(20);
  201.    InitSemaphore(print_q_semaphore);
  202.  
  203. /* get space for preferences */
  204.    prefs = (struct Preferences *)
  205.       AllocMem((ULONG)sizeof(struct Preferences), MEMORY_TYPE);
  206.    if(!prefs)
  207.       done(20);
  208.  
  209. /* Open libraries */
  210.    IntuitionBase = (struct IntuitionBase *)OpenLibrary("intuition.library", 36L);
  211.    if(IntuitionBase == NULL)
  212.       done(20);
  213.  
  214.    GfxBase = OpenLibrary("graphics.library", 36L);
  215.    if(GfxBase == NULL)
  216.       done(20);
  217.  
  218.    IconBase = OpenLibrary("icon.library", 36L);
  219.    if(IconBase == NULL)
  220.       done(20);
  221.  
  222.    WorkbenchBase = OpenLibrary("workbench.library", 36L);
  223.    if(WorkbenchBase == NULL)
  224.       done(20);
  225.  
  226.    AslBase = OpenLibrary("asl.library", 36L);
  227.    if(AslBase == NULL)
  228.       done(20);
  229.  
  230. /* Create port for AppIcon */
  231.    AppPort = CreatePort("WBPrinter", 0L);
  232.    if(AppPort == NULL)
  233.       done(20);
  234.  
  235. /* Try to find my icon */
  236.    Me = FindTask(NULL);
  237.  
  238.    icon = GetDiskObject((char *)Me->tc_Node.ln_Name);
  239.    if(icon == NULL)
  240.       done(20);
  241.  
  242. /* find out which directory to use for spooling */
  243.    spooldir = NULL;
  244.    tooltype = FindToolType(icon->do_ToolTypes, "SPOOLDIR");
  245.    if(!tooltype)
  246.       tooltype = (char *)&"RAM:";
  247.    spooldir = AllocMem(strlen(tooltype) + 1, MEMORY_TYPE);
  248.    if(spooldir);
  249.       strcpy(spooldir, tooltype);
  250.  
  251. /* let's see about Skip Perf and Page Eject */
  252.    tooltype = FindToolType(icon->do_ToolTypes, "SKIP_PERF");
  253.    if(tooltype)
  254.    {
  255.       if(stricmp(tooltype, "FALSE"))
  256.          PrtPrefs.pp_SkipPerf = TRUE;
  257.       else
  258.          PrtPrefs.pp_SkipPerf = FALSE;
  259.    }
  260.    else
  261.       PrtPrefs.pp_SkipPerf = TRUE;
  262.    tooltype = FindToolType(icon->do_ToolTypes, "EJECT_PAGE");
  263.    if(tooltype)
  264.    {
  265.       if(stricmp(tooltype, "FALSE"))
  266.          PrtPrefs.pp_EjectPage = TRUE;
  267.       else
  268.          PrtPrefs.pp_EjectPage = FALSE;
  269.    }
  270.    else
  271.       PrtPrefs.pp_EjectPage = TRUE;
  272.  
  273. /* let's see where the user wants to put the icon */
  274.    icon_left = NO_ICON_POSITION;
  275.    icon_top  = NO_ICON_POSITION;
  276.    tooltype = FindToolType(icon->do_ToolTypes, "ICON_LEFT_EDGE");
  277.    if(tooltype)
  278.       icon_left = atol(tooltype);
  279.    tooltype = FindToolType(icon->do_ToolTypes, "ICON_TOP_EDGE");
  280.    if(tooltype)
  281.       icon_top = atol(tooltype);
  282.  
  283. /* see if the user wants to use a different icon */
  284.    tooltype = FindToolType(icon->do_ToolTypes, "ICON");
  285.  
  286.    if(tooltype)
  287.    {
  288.       icon = GetDiskObject(tooltype);
  289.       if(icon == NULL)
  290.          done(20);
  291.    };
  292.  
  293.    icon->do_CurrentX = icon_left;
  294.    icon->do_CurrentY = icon_top;
  295.  
  296.    Appicon = AddAppIconA(0, 0, "Printer", AppPort, NULL, icon, NULL);
  297.    if(Appicon == NULL)
  298.       done(20);
  299.  
  300.    GetPrefs(prefs, sizeof(struct Preferences));
  301.  
  302.    if(prefs->PrintSpacing == SIX_LPI)
  303.       PrtPrefs.pp_LinesPerInch = 0;
  304.    else
  305.       PrtPrefs.pp_LinesPerInch = 1;
  306.  
  307.    if(prefs->PrintQuality)
  308.       PrtPrefs.pp_PrintQuality = 1;
  309.    else
  310.       PrtPrefs.pp_PrintQuality = 0;
  311.  
  312.    if(prefs->PrintPitch == PICA)
  313.       PrtPrefs.pp_PrintPitch = 0;
  314.    if(prefs->PrintPitch == ELITE)
  315.       PrtPrefs.pp_PrintPitch = 1;
  316.    if(prefs->PrintPitch == FINE)
  317.       PrtPrefs.pp_PrintPitch = 2;
  318.  
  319.    PrtPrefs.pp_LeftMargin = (UWORD)prefs->PrintLeftMargin;
  320.  
  321.    PrtPrefs.pp_RightMargin = (UWORD)prefs->PrintRightMargin;
  322.  
  323.    return;
  324. }
  325.  
  326.  
  327. /*
  328.  * Send a message to the print task
  329.  */
  330. void Tell_Print_Task(WORD tell)
  331. {
  332.    struct PrtMsg   *mess;
  333.    struct MsgPort  *tport;
  334.    struct MsgPort  *rport;
  335.  
  336.  
  337.    tport = FindPort("WBPrinter Printer");
  338.    if(!tport)
  339.       return;
  340.  
  341.    rport = CreatePort(NULL, NULL);
  342.    if(!rport)
  343.       return;
  344.  
  345.    mess = (struct PrtMsg *)AllocMem(sizeof(struct PrtMsg), MEMORY_TYPE);
  346.    if(!mess)
  347.    {
  348.       DeletePort(rport);
  349.       return;
  350.    };
  351.  
  352.    mess->pm_Command = tell;
  353.    mess->pm_Message.mn_Node.ln_Type = NT_MESSAGE;
  354.    mess->pm_Message.mn_ReplyPort    = rport;
  355.    mess->pm_Message.mn_Length       = 2;
  356.  
  357.    PutMsg(tport, (struct Message *)mess);
  358.    WaitPort(rport);
  359.    GetMsg(rport);
  360.  
  361.    FreeMem(mess, sizeof(struct PrtMsg));
  362.    DeletePort(rport);
  363.  
  364.    return;
  365. }
  366.  
  367.  
  368. /*
  369.  * Clear_Print_Q - remove all unprinted files from spool dir 
  370.  *                 and free list nodes.
  371.  */
  372. void Clear_Print_Q(void)
  373. {
  374.    BPTR             lock,
  375.                     oldcd;
  376.  
  377.    struct FileNode *fn;
  378.  
  379.    lock = Lock(spooldir, ACCESS_READ);
  380.    if(!lock)
  381.       return;
  382.  
  383.    oldcd = CurrentDir(lock);
  384.  
  385.    while(fn = (struct FileNode *)RemHead(Print_Q))
  386.    {
  387.       DeleteFile(fn->nn_SpooledName);
  388.       FreeMem(fn->nn_SpooledName, (strlen(fn->nn_SpooledName) + 1));
  389.       FreeMem(fn->nn_Node.ln_Name, (strlen(fn->nn_Node.ln_Name) + 1));
  390.       FreeMem(fn, sizeof(struct FileNode));
  391.    }
  392.  
  393.    CurrentDir(oldcd);
  394. }
  395.  
  396.  
  397. /*
  398.  * done - just clean up that which is open, and then leave.
  399.  */
  400. void done(int how)
  401. {
  402.  
  403.    if(Appicon) RemoveAppIcon(Appicon);
  404.    if(AppPort) DeletePort(AppPort);
  405.    if(icon) FreeDiskObject(icon);
  406.    if(IconBase) CloseLibrary(IconBase);
  407.    if(GfxBase) CloseLibrary(GfxBase);
  408.    if(WorkbenchBase) CloseLibrary(WorkbenchBase);
  409.    if(AslBase) CloseLibrary(AslBase);
  410.    if(prefs) FreeMem(prefs, sizeof(struct Preferences));
  411.  
  412.    if(IntuitionBase)
  413.    {
  414.       OpenWorkBench();         /* As requested */
  415.       CloseLibrary((struct Library *)IntuitionBase);
  416.    };
  417.  
  418.    if(Print_Q) FreeMem(Print_Q, sizeof(struct List));
  419.    if(print_q_semaphore) FreeMem(print_q_semaphore, sizeof(struct SignalSemaphore));
  420.    if(spooldir) FreeMem(spooldir, strlen(spooldir) + 1);
  421.  
  422.    exit(how);
  423. }
  424.  
  425.  
  426. int Do_AppWindow(void)
  427. {
  428.    struct IntuiMessage  *IMsg;
  429.    struct Gadget        *Gad;
  430.    struct FileNode      *fn;
  431.    struct FileRequester *FileReq;
  432.    WORD                  selected;
  433.    int                   i;
  434.  
  435.  
  436.    if(Make_AppWindow())
  437.       return(0);
  438.  
  439.    selected = -1;
  440.    while(1)
  441.    {
  442.       WaitPort(Wnd->UserPort);
  443.       while(IMsg = GT_GetIMsg(Wnd->UserPort))
  444.       {
  445.          if(IMsg->Class == IDCMP_CLOSEWINDOW)
  446.          {
  447.             GT_ReplyIMsg(IMsg);
  448.             Remove_AppWindow();
  449.             return(0);
  450.          };
  451.          if(IMsg->Class == IDCMP_GADGETUP)
  452.          {
  453.             Gad = (struct Gadget *)(IMsg->IAddress);
  454.             switch(Gad->GadgetID)
  455.             {
  456.                case GD_LPI_Gad:
  457.                   PrtPrefs.pp_LinesPerInch = IMsg->Code;
  458.                   break;
  459.  
  460.                case GD_Skip_Perf_Gad:
  461.                   if(Gad->Flags & SELECTED)
  462.                      PrtPrefs.pp_SkipPerf = 1;
  463.                   else
  464.                      PrtPrefs.pp_SkipPerf = 0;
  465.                   break;
  466.  
  467.                case GD_Page_Eject_Gad:
  468.                   if(Gad->Flags & SELECTED)
  469.                      PrtPrefs.pp_EjectPage = TRUE;
  470.                   else
  471.                      PrtPrefs.pp_EjectPage = FALSE;
  472.                   break;
  473.  
  474.                case GD_Quality_Gad:
  475.                   PrtPrefs.pp_PrintQuality = IMsg->Code;
  476.                   break;
  477.  
  478.                case GD_Pitch_Gad:
  479.                   PrtPrefs.pp_PrintPitch = IMsg->Code;
  480.                   break;
  481.  
  482.                case GD_L_Marg_Gad:
  483.                   PrtPrefs.pp_LeftMargin =
  484.                      (UWORD)((struct StringInfo *)(Gad->SpecialInfo))->LongInt;
  485.                   break;
  486.  
  487.                case GD_R_Marg_Gad:
  488.                   PrtPrefs.pp_RightMargin =
  489.                      (UWORD)((struct StringInfo *)(Gad->SpecialInfo))->LongInt;
  490.                   break;
  491.  
  492.                case GD_Pref_Gad:
  493.                   GetPrefs(prefs, sizeof(struct Preferences));
  494.                   if(prefs->PrintSpacing == SIX_LPI)
  495.                      PrtPrefs.pp_LinesPerInch = 0;
  496.                   else
  497.                      PrtPrefs.pp_LinesPerInch = 1;
  498.                   if(prefs->PrintQuality)
  499.                      PrtPrefs.pp_PrintQuality = 1;
  500.                   else
  501.                      PrtPrefs.pp_PrintQuality = 0;
  502.                   if(prefs->PrintPitch == PICA)
  503.                      PrtPrefs.pp_PrintPitch = 0;
  504.                   if(prefs->PrintPitch == ELITE)
  505.                      PrtPrefs.pp_PrintPitch = 1;
  506.                   if(prefs->PrintPitch == FINE)
  507.                      PrtPrefs.pp_PrintPitch = 2;
  508.                   PrtPrefs.pp_LeftMargin  = (UWORD)prefs->PrintLeftMargin;
  509.                   PrtPrefs.pp_RightMargin = (UWORD)prefs->PrintRightMargin;
  510.                   GT_SetGadgetAttrs(Gadgets[GD_LPI_Gad], Wnd, NULL,
  511.                                  GTCY_Active, (ULONG)PrtPrefs.pp_LinesPerInch,
  512.                                  TAG_DONE);
  513.                   GT_SetGadgetAttrs(Gadgets[GD_Quality_Gad], Wnd, NULL,
  514.                                  GTCY_Active, (ULONG)PrtPrefs.pp_PrintQuality,
  515.                                  TAG_DONE);
  516.                   GT_SetGadgetAttrs(Gadgets[GD_Pitch_Gad], Wnd, NULL,
  517.                                  GTCY_Active, (ULONG)PrtPrefs.pp_PrintPitch,
  518.                                  TAG_DONE);
  519.                   GT_SetGadgetAttrs(Gadgets[GD_L_Marg_Gad], Wnd, NULL,
  520.                                  GTIN_Number, (ULONG)PrtPrefs.pp_LeftMargin,
  521.                                  TAG_DONE);
  522.                   GT_SetGadgetAttrs(Gadgets[GD_R_Marg_Gad], Wnd, NULL,
  523.                                  GTIN_Number, (ULONG)PrtPrefs.pp_RightMargin,
  524.                                  TAG_DONE);
  525.                   GT_RefreshWindow(Wnd, NULL);
  526.                   break;
  527.  
  528.                case GD_Spool_Gad:
  529.                   FileReq = AllocAslRequestTags(ASL_FileRequest,
  530.                                     ASL_Hail, &"CHOOSE SPOOL DIRECTORY",
  531.                                     ASL_Window, Wnd,
  532.                                     ASL_Dir, spooldir,
  533.                                     ASL_ExtFlags1, FIL1F_NOFILES,
  534.                                     TAG_DONE);
  535.  
  536.                   if(FileReq)
  537.                   {
  538.                      if(AslRequest(FileReq, NULL))
  539.                      {
  540.                         if(spooldir)
  541.                            FreeMem(spooldir, strlen(spooldir) + 1);
  542.                         spooldir = AllocMem(strlen(FileReq->rf_Dir) + 1, MEMORY_TYPE);
  543.                         if(!spooldir)
  544.                            break;
  545.                         strcpy(spooldir,
  546.                             ((struct FileRequester *)FileReq)->rf_Dir);
  547.                      };
  548.                      FreeAslRequest(FileReq);
  549.                      FileReq = NULL;
  550.                   };
  551.                   break;
  552.  
  553.                case GD_Next_Gad:
  554.                   if(selected >= 0)
  555.                   {
  556.                      i = 0;
  557.                      ObtainSemaphore(print_q_semaphore);
  558.                      for(fn = (struct FileNode *)Print_Q->lh_Head;
  559.                          i++ < selected;
  560.                          fn = (struct FileNode *)fn->nn_Node.ln_Succ);
  561.                      if(fn->nn_Node.ln_Type == PRINT_FILE)
  562.                      {
  563.                         Remove((struct Node *)fn);
  564.                         if(Print_Q->lh_Head->ln_Type == PRINT_FILE)
  565.                         {
  566.                            AddHead(Print_Q, (struct Node *)fn);
  567.                            selected = 0;
  568.                         }
  569.                         else
  570.                         {
  571.                            Insert(Print_Q, (struct Node *)fn, Print_Q->lh_Head);
  572.                            selected = 1;
  573.                         };
  574.                         GT_SetGadgetAttrs(Gadgets[GD_Job_List_Gad], Wnd, NULL,
  575.                                           GTLV_Selected, (ULONG)selected,
  576.                                           TAG_DONE);
  577.                      }
  578.                      GT_RefreshWindow(Wnd, NULL);
  579.                      ReleaseSemaphore(print_q_semaphore);
  580.                   };
  581.                   break;
  582.  
  583.                case GD_Cancel_Gad:
  584.                   if(selected >= 0)
  585.                   {
  586.                      i = 0;
  587.                      ObtainSemaphore(print_q_semaphore);
  588.                      for(fn = (struct FileNode *)Print_Q->lh_Head;
  589.                          i++ < selected;
  590.                          fn = (struct FileNode *)fn->nn_Node.ln_Succ);
  591.                      if(fn->nn_Node.ln_Type == PRINTING_FILE)
  592.                         Tell_Print_Task(CANCEL_PRINT);
  593.                      Remove((struct Node *)fn);
  594.                      if(fn->nn_Node.ln_Type != PRINTING_FILE)
  595.                      {
  596.                         strcpy(Name_Buffer, spooldir);
  597.                         AddPart(Name_Buffer, fn->nn_SpooledName, 255);
  598.                         DeleteFile(Name_Buffer);
  599.                      };
  600.                      FreeMem(fn->nn_SpooledName,
  601.                             (strlen(fn->nn_SpooledName) + 1));
  602.                      FreeMem(fn->nn_Node.ln_Name,
  603.                             (strlen(fn->nn_Node.ln_Name) + 1));
  604.                      FreeMem(fn, sizeof(struct FileNode));
  605.  
  606.                      GT_SetGadgetAttrs(Gadgets[GD_Job_List_Gad], Wnd, NULL,
  607.                                        GTLV_Selected, (ULONG)~0,
  608.                                        TAG_DONE);
  609.                      GT_RefreshWindow(Wnd, NULL);
  610.                      ReleaseSemaphore(print_q_semaphore);
  611.                   };
  612.                   break;
  613.  
  614.                case GD_Job_List_Gad:
  615.                   selected = IMsg->Code;
  616.                   break;
  617.  
  618.                case GD_Quit_Gad:
  619.                   GT_ReplyIMsg(IMsg);
  620.                   Tell_Print_Task(CANCEL_AND_DIE);
  621.                   Remove_AppWindow();
  622.                   return(20);
  623.                   break;
  624.             };
  625.          };
  626.          GT_ReplyIMsg(IMsg);
  627.       };
  628.    };
  629. }
  630.  
  631. /*
  632.  *  Source generated with GadToolsBox V1.0
  633.  *  which is (c) Copyright 1991 Jaba Development
  634.  *
  635.  *
  636.  *  Source modified by Mike Ruble to handle dynamic gadget placements
  637.  *  and sizes based on the current screen font.
  638.  *
  639.  */
  640. int Make_AppWindow( void )
  641. {
  642.     struct NewGadget     ng;
  643.     struct Gadget       *g;
  644.     WORD                 button_height;
  645.     WORD                 integer_height;
  646.     WORD                 gadget_top;
  647.     WORD                 gadget_width;
  648.     WORD                 integer_width;
  649.  
  650.  
  651.     GadToolsBase  = OpenLibrary("gadtools.library", 36L);
  652.     if(!GadToolsBase)
  653.        return(20);
  654.  
  655. /* Get address of Default Public Screen */
  656.     if ( NOT( Scr = LockPubScreen( NULL )))
  657.         return( 1l );
  658.  
  659. /* Set Screen address for Window */
  660.     WindowTags[ 8 ].ti_Data = (ULONG)Scr;
  661.  
  662. /* Set Gadget heights based on text height */
  663.     button_height  = (Scr->Font)->ta_YSize + 4;
  664.     integer_height = button_height + 1;
  665.  
  666. /* where Gadgets should begin - also based on font height */
  667.     gadget_top     = button_height + 1;
  668.  
  669. /* determine width for gadgets by finding pixel length of longest string */
  670.     gadget_width   = (WORD)TextLength(&(Scr->RastPort), "Set Spool Directory", 19);
  671.     gadget_width  += 10;
  672.     integer_width  = (WORD)TextLength(&(Scr->RastPort), "MMMM", 4);
  673.     integer_width += 12;
  674.  
  675. /* alter window size and position to fit gadgets */
  676.     WindowTags[ 2 ].ti_Data = (LONG)((gadget_width * 2) + 34);
  677.     WindowTags[ 3 ].ti_Data = (LONG)((button_height * 7) + (integer_height * 2)
  678.                                      + gadget_top + 25);
  679.     if(window_left)
  680.        WindowTags[ 0 ].ti_Data = window_left;
  681.     else
  682.        WindowTags[ 0 ].ti_Data = (ULONG)((struct IntuitionBase *)IntuitionBase)->MouseX + 100;
  683.     if(window_top)
  684.        WindowTags[ 1 ].ti_Data = window_top;
  685.     else
  686.        WindowTags[ 1 ].ti_Data = (ULONG)((struct IntuitionBase *)IntuitionBase)->MouseY - (WindowTags[ 3 ].ti_Data / 2);
  687.  
  688.     if ( NOT( VisualInfo = GetVisualInfo( Scr, TAG_DONE )))
  689.         return( 2l );
  690.  
  691.     if ( NOT( g = CreateContext( &GList )))
  692.         return( 3l );
  693.  
  694.     ng.ng_LeftEdge        =    12;
  695.     ng.ng_TopEdge         =    gadget_top;
  696.     ng.ng_Width           =    gadget_width;
  697.     ng.ng_Height          =    button_height;
  698.     ng.ng_GadgetText      =    0l;
  699.     ng.ng_TextAttr        =    Scr->Font;
  700.     ng.ng_GadgetID        =    GD_LPI_Gad;
  701.     ng.ng_Flags           =    0;
  702.     ng.ng_VisualInfo      =    VisualInfo;
  703.  
  704.     g = CreateGadget( CYCLE_KIND, g, &ng, GTCY_Labels, LPI_GadLabels,
  705.                                           GTCY_Active, (ULONG)PrtPrefs.pp_LinesPerInch,
  706.                                           TAG_DONE );
  707.  
  708.     Gadgets[GD_LPI_Gad] = g;
  709.  
  710.     ng.ng_TopEdge         +=   button_height;
  711.     ng.ng_GadgetText      =    0l;
  712.     ng.ng_GadgetID        =    GD_Quality_Gad;
  713.  
  714.     g = CreateGadget( CYCLE_KIND, g, &ng, GTCY_Labels, Quality_GadLabels,
  715.                                           GTCY_Active, (ULONG)PrtPrefs.pp_PrintQuality,
  716.                                           TAG_DONE );
  717.  
  718.     Gadgets[GD_Quality_Gad] = g;
  719.  
  720.     ng.ng_TopEdge         +=   button_height;
  721.     ng.ng_GadgetText      =    0l;
  722.     ng.ng_GadgetID        =    GD_Pitch_Gad;
  723.  
  724.     g = CreateGadget( CYCLE_KIND, g, &ng, GTCY_Labels, Pitch_GadLabels,
  725.                                           GTCY_Active, (ULONG)PrtPrefs.pp_PrintPitch,
  726.                                           TAG_DONE );
  727.  
  728.     Gadgets[GD_Pitch_Gad] = g;
  729.  
  730.     ng.ng_LeftEdge        +=   (gadget_width - integer_width);
  731.     ng.ng_TopEdge         +=   (button_height + 5);
  732.     ng.ng_Width           =    integer_width;
  733.     ng.ng_Height          =    integer_height;
  734.     ng.ng_GadgetText      =    "Left  Margin:";
  735.     ng.ng_GadgetID        =    GD_L_Marg_Gad;
  736.     ng.ng_Flags           =    PLACETEXT_LEFT;
  737.  
  738.     g = CreateGadget( INTEGER_KIND, g, &ng, GTIN_Number, (ULONG)PrtPrefs.pp_LeftMargin,
  739.                                             GTIN_MaxChars, 10,
  740.                                             TAG_DONE );
  741.  
  742.     Gadgets[GD_L_Marg_Gad] = g;
  743.  
  744.     ng.ng_TopEdge         +=   integer_height;
  745.     ng.ng_GadgetText      =    "Right Margin:";
  746.     ng.ng_GadgetID        =    GD_R_Marg_Gad;
  747.  
  748.     g = CreateGadget( INTEGER_KIND, g, &ng, GTIN_Number, (ULONG)PrtPrefs.pp_RightMargin,
  749.                                             GTIN_MaxChars, 10,
  750.                                             TAG_DONE );
  751.  
  752.     Gadgets[GD_R_Marg_Gad] = g;
  753.  
  754.     ng.ng_LeftEdge        =    12;
  755.     ng.ng_TopEdge         +=   (integer_height + 5);
  756.     ng.ng_Width           =    gadget_width;
  757.     ng.ng_Height          =    button_height;
  758.     ng.ng_GadgetText      =    "From Preferences";
  759.     ng.ng_GadgetID        =    GD_Pref_Gad;
  760.     ng.ng_Flags           =    PLACETEXT_IN;
  761.  
  762.     g = CreateGadget( BUTTON_KIND, g, &ng, TAG_DONE );
  763.  
  764.     Gadgets[GD_Pref_Gad] = g;
  765.  
  766.     ng.ng_LeftEdge        +=   (gadget_width - 26);
  767.     ng.ng_TopEdge         +=   (integer_height + 5);
  768.     ng.ng_Width           =    25;
  769.     ng.ng_Height          =    button_height;
  770.     ng.ng_GadgetText      =    "Skip Perforation";
  771.     ng.ng_GadgetID        =    GD_Skip_Perf_Gad;
  772.     ng.ng_Flags           =    PLACETEXT_LEFT;
  773.  
  774.     g = CreateGadget( CHECKBOX_KIND, g, &ng, GTCB_Checked, (ULONG)PrtPrefs.pp_SkipPerf, TAG_DONE );
  775.  
  776.     Gadgets[GD_Skip_Perf_Gad] = g;
  777.  
  778.     ng.ng_TopEdge         +=   button_height;
  779.     ng.ng_GadgetText      =    "Eject Page";
  780.     ng.ng_GadgetID        =    GD_Page_Eject_Gad;
  781.  
  782.     g = CreateGadget( CHECKBOX_KIND, g, &ng, GTCB_Checked, (ULONG)PrtPrefs.pp_EjectPage, TAG_DONE );
  783.  
  784.     Gadgets[GD_Page_Eject_Gad] = g;
  785.  
  786.     ng.ng_LeftEdge        =    ((WindowTags[2].ti_Data / 2) - (gadget_width / 2));
  787.     ng.ng_TopEdge         +=   (button_height + 5);
  788.     ng.ng_Width           =    gadget_width;
  789.     ng.ng_Height          =    button_height;
  790.     ng.ng_GadgetText      =    "Quit WBPrinter";
  791.     ng.ng_GadgetID        =    GD_Quit_Gad;
  792.     ng.ng_Flags           =    PLACETEXT_IN;
  793.  
  794.     g = CreateGadget( BUTTON_KIND, g, &ng, TAG_DONE );
  795.  
  796.     Gadgets[GD_Quit_Gad] = g;
  797.  
  798.     ng.ng_LeftEdge        =    12 + (gadget_width + 10);
  799.     ng.ng_TopEdge         -=   (button_height + 5);
  800.     ng.ng_GadgetText      =    "Set Spool Directory";
  801.     ng.ng_GadgetID        =    GD_Spool_Gad;
  802.  
  803.     g = CreateGadget( BUTTON_KIND, g, &ng, TAG_DONE );
  804.  
  805.     Gadgets[GD_Spool_Gad] = g;
  806.  
  807.     ng.ng_TopEdge         -=   (button_height + 5);
  808.     ng.ng_Width           =    (gadget_width / 2);
  809.     ng.ng_GadgetText      =    "NEXT";
  810.     ng.ng_GadgetID        =    GD_Next_Gad;
  811.  
  812.     g = CreateGadget( BUTTON_KIND, g, &ng, TAG_DONE );
  813.  
  814.     Gadgets[GD_Next_Gad] = g;
  815.  
  816.     ng.ng_LeftEdge        +=   ng.ng_Width;
  817.     ng.ng_Width           =    (gadget_width - ng.ng_Width);
  818.     ng.ng_GadgetText      =    "CANCEL";
  819.     ng.ng_GadgetID        =    GD_Cancel_Gad;
  820.  
  821.     g = CreateGadget( BUTTON_KIND, g, &ng, TAG_DONE );
  822.  
  823.     Gadgets[GD_Cancel_Gad] = g;
  824.  
  825.     ng.ng_LeftEdge        =    12 + (gadget_width + 10);
  826.     ng.ng_Height          =    (ng.ng_TopEdge - gadget_top);
  827.     ng.ng_TopEdge         =    gadget_top;
  828.     ng.ng_Width           =    gadget_width;
  829.     ng.ng_GadgetText      =    0l;
  830.     ng.ng_GadgetID        =    GD_Job_List_Gad;
  831.     ng.ng_Flags           =    0;
  832.  
  833.     g = CreateGadget( LISTVIEW_KIND, g, &ng, GTLV_Labels, Print_Q, GTLV_ShowSelected, 0l, TAG_DONE );
  834.  
  835.     Gadgets[GD_Job_List_Gad] = g;
  836.  
  837.  
  838.     if ( NOT g )
  839.         return( 4l );
  840.  
  841.     WindowTags[ 6 ].ti_Data = (ULONG)GList;
  842.  
  843.     if ( NOT( Wnd = OpenWindowTagList( 0l, WindowTags )))
  844.         return( 5l );
  845.  
  846.     GT_RefreshWindow( Wnd, 0l );
  847.  
  848.     return( 0l );
  849. }
  850.  
  851. void Remove_AppWindow( void )
  852. {
  853.     struct Message *msg;
  854.  
  855.     if ( Wnd        )
  856.     {
  857.         window_left = (ULONG)Wnd->LeftEdge;
  858.         window_top  = (ULONG)Wnd->TopEdge;
  859.         while(msg = GetMsg(Wnd->UserPort))
  860.            ReplyMsg(msg);
  861.         CloseWindow( Wnd );
  862.         Wnd = NULL;
  863.     }
  864.  
  865.     if ( GList      )
  866.     {
  867.         FreeGadgets( GList );
  868.         GList = NULL;
  869.     }
  870.  
  871.     if ( VisualInfo )
  872.     {
  873.         FreeVisualInfo( VisualInfo );
  874.         VisualInfo = NULL;
  875.     }
  876.  
  877.     if ( Scr        )
  878.     {
  879.         UnlockPubScreen( NULL, Scr );
  880.         Scr = NULL;
  881.     }
  882.  
  883.     if ( GadToolsBase )
  884.     {
  885.         CloseLibrary( GadToolsBase );
  886.         GadToolsBase = NULL;
  887.     }
  888. }
  889.    
  890.  
  891. /*
  892.  * Start up the print task
  893.  */
  894. void StartPrintTask( void )
  895. {
  896.    struct MsgPort *child_port;
  897.    struct Process *child_proc;
  898.    struct TagItem  proc_tags[3];
  899.    
  900.    /* Allocate memory for both fake seglist and startup message */
  901.    /* If either fail we can return, before the CreateProc()     */ 
  902.    start_msg = (struct ProcMsg *)AllocMem(sizeof(struct ProcMsg), MEMORY_TYPE);
  903.    if (start_msg == NULL)
  904.       return;
  905.  
  906.  
  907.    proc_tags[0].ti_Tag  = NP_Entry;
  908.    proc_tags[0].ti_Data = (ULONG)&PrintFiles;
  909.    proc_tags[1].ti_Tag  = NP_Name;
  910.    proc_tags[1].ti_Data = (ULONG)&"WBPrinter_Print";
  911.    proc_tags[2].ti_Tag  = TAG_DONE;
  912.    proc_tags[2].ti_Data = NULL;
  913.  
  914.    if((child_proc = CreateNewProc(&proc_tags[0])) == NULL)
  915.    {
  916.       /* error, cleanup and abort */
  917.       FreeMem(start_msg, sizeof(*start_msg));
  918.       return;
  919.    }
  920.    child_port = &(child_proc->pr_MsgPort);
  921.    
  922.    /* Create the startup message */
  923.    start_msg->msg.mn_Length = sizeof(struct ProcMsg) - sizeof(struct Message);
  924.    start_msg->msg.mn_ReplyPort = CreatePort(0,0);
  925.    start_msg->msg.mn_Node.ln_Type = NT_MESSAGE;
  926.    
  927.    start_msg->global_data = (void *)getreg(REG_A4);  /* save global data reg (A4) */
  928.    
  929.    /* Fill in user fields here */
  930.    
  931.    
  932.    /* send startup message to child */
  933.    PutMsg(child_port, (struct Message *)start_msg);
  934.    
  935.    return;
  936. }
  937.  
  938.  
  939. /*
  940.  * Send file to PRT:
  941.  */
  942. __saveds void PrintFiles()
  943. {
  944.    struct Process  *proc;
  945.    struct ProcMsg  *mess;
  946.    struct PrtMsg   *pmsg;
  947.    struct FileNode *fnode;
  948.    struct MsgPort  *child_msg_port;
  949.    FILE   *infile,
  950.           *printer;
  951.    long   lcount;
  952.    char   *buff;
  953.    char   file_name[255];
  954.    BOOL   print_done;
  955.    BOOL   kill_task;
  956.    BOOL   canceled;
  957.    int    i;
  958.  
  959.          
  960.    proc = (struct Process *)FindTask((char *)NULL);
  961.  
  962.    /* get the startup message */
  963.    WaitPort(&proc->pr_MsgPort);
  964.    mess = (struct ProcMess *)GetMsg(&proc->pr_MsgPort);
  965.  
  966.    child_msg_port = CreatePort("WBPrinter Printer", 0L);
  967.    if(child_msg_port == NULL)
  968.       goto endprint;
  969.  
  970.    kill_task = canceled = FALSE;
  971.    while(!kill_task)
  972.    {
  973.       ObtainSemaphore(print_q_semaphore);
  974.       fnode = (struct FileNode *)Print_Q->lh_Head;
  975.       ReleaseSemaphore(print_q_semaphore);
  976.       while(fnode->nn_Node.ln_Succ)
  977.       {
  978.          ObtainSemaphore(print_q_semaphore);
  979.          fnode->nn_Node.ln_Type = PRINTING_FILE;
  980.          strcpy(file_name, spooldir);
  981.          AddPart(file_name, fnode->nn_SpooledName, 255);
  982.          ReleaseSemaphore(print_q_semaphore);
  983.  
  984.          if((infile = fopen(file_name, "r")) == NULL)
  985.             return;
  986.  
  987.          if((printer = fopen("PRT:", "a+")) == NULL)
  988.          {
  989.             fclose(infile);
  990.             return;
  991.          }
  992.          if((buff = (char *)AllocMem(1024, MEMF_PUBLIC)) == NULL)
  993.          {
  994.             fclose(infile);
  995.             fclose(printer);
  996.             return;
  997.          }
  998.          strcpy(buff, PrinterSetup[LPI   + PrtPrefs.pp_LinesPerInch]);
  999.          strcat(buff, PrinterSetup[SKIP  + PrtPrefs.pp_SkipPerf]);
  1000.          if(buff[6] == 'n')
  1001.             buff[6] = (char)((PrtPrefs.pp_LinesPerInch + 3) * 2) + '0';
  1002.          strcat(buff, PrinterSetup[QUAL  + PrtPrefs.pp_PrintQuality]);
  1003.          strcat(buff, PrinterSetup[PITCH + PrtPrefs.pp_PrintPitch]);
  1004.          sprintf(&buff[17], "\x1b[%d;%ds",
  1005.                  PrtPrefs.pp_LeftMargin, PrtPrefs.pp_RightMargin);
  1006.          i = 17 + strlen(&buff[17]);
  1007.          fwrite(buff, i, 1, printer);
  1008.  
  1009.          lcount = 0;
  1010.          print_done = FALSE;
  1011.          while(!print_done)
  1012.          {
  1013.             if(fgets(buff, 1024, infile) == NULL)
  1014.                print_done = TRUE;
  1015.             else
  1016.                fputs(buff, printer);
  1017.             if(++lcount == 10)
  1018.             {
  1019.                lcount = 0;
  1020.                while(pmsg = (struct PrtMsg *)GetMsg(child_msg_port))
  1021.                {
  1022.                   switch(pmsg->pm_Command)
  1023.                   {
  1024.                      case CANCEL_AND_DIE:
  1025.                         kill_task  = TRUE;
  1026.                         print_done = TRUE;
  1027.                         break;
  1028.                      case CANCEL_PRINT:
  1029.                         print_done = TRUE;
  1030.                         canceled   = TRUE;
  1031.                         break;
  1032.                   };
  1033.                   ReplyMsg((struct Message *)pmsg);
  1034.                };
  1035.             };
  1036.          };
  1037.          fclose(infile);
  1038.          if(PrtPrefs.pp_EjectPage)
  1039.          {
  1040.             buff[0] = '\x0c';
  1041.             buff[1] = '\0';
  1042.             fputs(buff, printer);
  1043.          };
  1044.          fclose(printer);
  1045.          FreeMem(buff, 1024);
  1046.          DeleteFile(file_name);
  1047.          while(AttemptSemaphore(print_q_semaphore) == FALSE)
  1048.          {
  1049.             Delay(120);
  1050.             while(pmsg = (struct PrtMsg *)GetMsg(child_msg_port))
  1051.             {
  1052.                switch(pmsg->pm_Command)
  1053.                {
  1054.                   case CANCEL_AND_DIE:
  1055.                      kill_task  = TRUE;
  1056.                      break;
  1057.                   case CANCEL_PRINT:
  1058.                      canceled   = TRUE;
  1059.                      break;
  1060.                };
  1061.                ReplyMsg((struct Message *)pmsg);
  1062.             };
  1063.          };
  1064.          if(!canceled) /* Do_AppWindow already Removed this Node if TRUE */
  1065.          {
  1066.             Remove((struct Node *)fnode);
  1067.             FreeMem(fnode->nn_SpooledName, (strlen(fnode->nn_SpooledName) + 1));
  1068.             FreeMem(fnode->nn_Node.ln_Name, (strlen(fnode->nn_Node.ln_Name) + 1));
  1069.             FreeMem(fnode, sizeof(struct FileNode));
  1070.          };
  1071.          canceled = FALSE;
  1072.          fnode = (struct FileNode *)Print_Q->lh_Head;
  1073.          ReleaseSemaphore(print_q_semaphore);
  1074.       };
  1075.       WaitPort(child_msg_port);
  1076.       while(pmsg = (struct PrtMsg *)GetMsg(child_msg_port))
  1077.       {
  1078.          switch(pmsg->pm_Command)
  1079.          {
  1080.             case CANCEL_AND_DIE:
  1081.                kill_task  = TRUE;
  1082.                break;
  1083.             case CANCEL_PRINT:
  1084.             case PRINTS_READY:
  1085.                break;
  1086.          };
  1087.          ReplyMsg((struct Message *)pmsg);
  1088.       };
  1089.    };   
  1090.  
  1091. endprint:
  1092.    /* Reply so process who spawed us knows we're done */   
  1093.    if(child_msg_port) DeletePort(child_msg_port);
  1094.    ReplyMsg((struct Message *)mess);
  1095. }
  1096.