home *** CD-ROM | disk | FTP | other *** search
/ ARM Club 3 / TheARMClub_PDCD3.iso / hensa / programming / desklib / sources / DeskLib / !DLSources / Libraries / Print / c / Print
Encoding:
Text File  |  1995-07-28  |  7.7 KB  |  337 lines

  1. #include <stdlib.h>
  2. #include <stdio.h>
  3.  
  4. #include "DeskLib:Wimp.h"
  5. #include "DeskLib:WimpSWIs.h"
  6. #include "DeskLib:PDriver.h"
  7. #include "DeskLib:Error.h"
  8. #include "DeskLib:File.h"
  9. #include "DeskLib:Event.h"
  10.  
  11. #include "DeskLib:Print.h"
  12.  
  13.  
  14.  
  15. typedef enum    {
  16.     print__progress_2,
  17.     print__progress_4_5,
  18.     print__progress_5,
  19.     print__progress_6,
  20.     print__progress_7
  21.     }
  22.     print__progress;
  23.     /* These correspond to the numbered paragraphs in PRMs 3-259.    */
  24.  
  25.  
  26. typedef struct    {
  27.  
  28.     print_block    public;
  29.     
  30.     int            message_ref;    /* id of the last event_SENDWANTACK we sent.    */
  31.     print__progress    progress;
  32.     print_printfn    printfn;
  33.     print_savefn    savefn;
  34.     print_resultfn    resultfn;
  35.     }
  36.     print__block;
  37.  
  38.  
  39. static void    Print__ClaimMessages( print__block *print);
  40. static void    Print__ReleaseMessages( print__block *print);
  41.  
  42. static void    Print__Finish( 
  43.     print__block    *print, 
  44.     BOOL            releasemsgs, 
  45.     print_result    result
  46.     );
  47.  
  48.  
  49.  
  50. static void    Print__PrintIt( print__block *print)
  51.     /* This is called when the Wimp messaging between us    */
  52.     /* and !Printers has finished.                */
  53. {
  54. os_error    *error;
  55.  
  56. Print__ReleaseMessages( print);
  57.  
  58. error =  PDriver_Info( &print->public.printerinfo);
  59. if (error)    {
  60.     Print__Finish( print, FALSE, (print_result) error);
  61.     return;
  62.     }
  63.  
  64. print->public.job = File_Open( "Printer:", file_WRITE);
  65. if ( !print->public.job)    {
  66.     Print__Finish( print, FALSE, print_result_CANTOPENPRINTER);
  67.     return;
  68.     }
  69.  
  70. error = PDriver_SelectJob( print->public.job, print->public.jobtitle, &print->public.oldjob);
  71. if (error)    {
  72.     Print__Finish( print, FALSE, (print_result) error);
  73.     return;
  74.     }
  75.  
  76. print->printfn( &print->public);
  77.  
  78. PDriver_EndJob( print->public.job);
  79. File_Close( print->public.job);
  80.  
  81. Print__Finish( print, FALSE, print_result_OK);
  82.  
  83. return;
  84. }
  85.  
  86.  
  87.  
  88.  
  89.  
  90. /*
  91. #ifndef message_PRINTERROR
  92. #define message_PRINTERROR 0x80144
  93. #endif
  94.  
  95. #ifndef message_PRINTSAVE
  96. #define message_PRINTSAVE 0x80142
  97. #endif
  98. */
  99.  
  100.  
  101. #define Message_IsBounce( event, oldref)            \
  102.     (                             \
  103.         (event)->type==event_USERMESSAGEACK        \
  104.         &&                         \
  105.         (event)->data.message.header.myref==(oldref)    \
  106.     )                             \
  107.     ?                             \
  108.     TRUE : FALSE;                        \
  109.     /* This returns TRUE if the event is our message being    */
  110.     /* returned to us by the wimp.                */
  111.  
  112. #define Message_IsReply( event, oldref)                        \
  113.     ( (event)->data.message.header.yourref == (oldref)) ? TRUE : FALSE    \
  114.  
  115.  
  116.  
  117.  
  118. static BOOL    Print__MessageHandler( event_pollblock *event, void *reference)
  119. {
  120. print__block    *print = (print__block *) reference;
  121. BOOL            reply;
  122. BOOL            bounced;
  123.  
  124. reply    = Message_IsReply( event, print->message_ref);
  125. bounced    = Message_IsBounce( event, print->message_ref);
  126.  
  127.  
  128. if ( print->progress == print__progress_2)    {
  129.  
  130.     if ( bounced)        {
  131.         /* PrintSave message bounced...    */
  132.         if ( print->printfn)    Print__PrintIt( print);
  133.         else    Print__Finish( print, TRUE, print_result_NEEDPRINTERMANAGER);
  134.             
  135.         return TRUE;
  136.         }
  137.     
  138.     else if ( reply && event->data.message.header.action == message_PRINTERROR)    {
  139.         Print__Finish( print, TRUE, print_result_PRINTERROR);
  140.         return TRUE;
  141.         }
  142.     
  143.     else if ( reply && event->data.message.header.action == message_PRINTFILE)    {
  144.         print->progress = print__progress_4_5;
  145.         return TRUE;
  146.         }
  147.     
  148.     else if ( reply && event->data.message.header.action == message_DATASAVEACK)    {
  149.         print->progress = print__progress_4_5;
  150.         }
  151.     }
  152.  
  153.  
  154. if ( print->progress == print__progress_4_5)    {
  155.  
  156.     if ( /*reply &&*/ event->data.message.header.action == message_PRINTTYPEODD)    {
  157.         message_block    message = event->data.message;
  158.         
  159.         if ( print->printfn)    {
  160.             /* We can print the file ourselves...    */
  161.             message.header.action    = message_PRINTTYPEKNOWN;
  162.             message.header.yourref    = event->data.message.header.myref;
  163.             message.header.size    = 256;
  164.             Wimp_SendMessage( 
  165.                 event_SEND, 
  166.                 &message, event->data.message.header.sender, 
  167.                 0
  168.                 );
  169.                 /* This is the last message of the protool, so we don't    */
  170.                 /* want it returned if not replied to.            */
  171.             Print__PrintIt( print);
  172.             return TRUE;
  173.             }
  174.         
  175.         else    {
  176.             /* We can't print directly, so we ignore message_PRINTTYPEODD    */
  177.             /*  - printers will send DATASAVEACK next    */
  178.             }
  179.             
  180.         return TRUE;
  181.         }
  182.     
  183.     else if ( reply && event->data.message.header.action == message_DATASAVEACK)    {
  184.         /* Save the file, for queing etc., to the filename specified. Then send    */
  185.         /* message_DATALOAD.                            */
  186.         /* wait for file to reach top of thr printer queue,            */
  187.         /* whereapon printers will send us a message_PRINTTYPEODD.        */
  188.         /* Note that Print_ doesn't deal with a broadcast PRINTTYPEODD.        */
  189.  
  190.         print->progress = print__progress_6;
  191.         if ( print->savefn)    {
  192.             message_block    reply;
  193.             BOOL        error;
  194.             
  195.             error = print->savefn( 
  196.                 &print->public, &event->data.message.data.datasaveack
  197.                 );
  198.             if (error)    {
  199.                 /* Couldn't save file.    */
  200.                 /*Error_Report( 0, "Couldn't save the data to be printed");*/
  201.                 /* Leave savefn to report the error.    */
  202.                 Print__Finish( print, TRUE, print_result_SAVEFAILED);
  203.                 return TRUE;
  204.                 }
  205.             
  206.             reply = event->data.message;
  207.             reply.header.action    = message_DATALOAD;
  208.             reply.header.yourref    = event->data.message.header.myref;
  209.             Wimp_SendMessage( 
  210.                 event_SENDWANTACK, 
  211.                 &reply, 
  212.                 event->data.message.header.sender,
  213.                 0
  214.                 );
  215.             print->message_ref = reply.header.myref;
  216.             
  217.             print->progress = print__progress_7;
  218.             return TRUE;
  219.             }
  220.         
  221.         else    {
  222.             Error_Report( 0, 
  223.                 "Printer busy, and we are unable to save "
  224.                 "data to be printed to printer queue"
  225.                 );
  226.             Print__Finish( print, TRUE, print_result_CANTSAVE);
  227.             }
  228.             
  229.         return TRUE;
  230.         }
  231.     }
  232.  
  233. if ( print->progress == print__progress_7)    {
  234.     if ( bounced)    {
  235.         Error_Report( 0, "Print bounced, progress_7");
  236.         Print__Finish( print, TRUE, print_result_FAILED);
  237.         return TRUE;
  238.         }    
  239.         
  240.     if ( reply && event->data.message.header.action == message_DATALOADACK)    {
  241.         Print__Finish( print, TRUE, print_result_QUEUED);
  242.         return TRUE;
  243.         }
  244.     }
  245.  
  246.  
  247. if (reply)    {
  248.     Error_ReportInternal( 0, 
  249.         "Unrecognised print reply %i, progress %i", 
  250.         event->data.message.header.action,
  251.         print->progress
  252.         );
  253.     Print__Finish( print, TRUE, print_result_FAILED);
  254.     return TRUE;
  255.     }
  256.  
  257. return FALSE;
  258. }
  259.  
  260.  
  261.  
  262.  
  263. BOOL    Print_StartPrint( 
  264.         print_printfn    printfn,
  265.         print_savefn    savefn,
  266.         print_resultfn    resultfn,
  267.         void            *reference, 
  268.         int            filetype,
  269.         int            estsize,
  270.         char            *leafname,
  271.         char            *jobtitle
  272.         )
  273. {
  274. message_block    message;
  275. print__block    *print = (print__block *) malloc( sizeof( print__block));
  276.  
  277. if ( !print)    {
  278.     Error_ReportInternal( 0, "Can't malloc print__block...");
  279.     return ERROR;
  280.     }
  281.  
  282.  
  283. print->printfn    = printfn;
  284. print->savefn    = savefn;
  285. print->resultfn    = resultfn;
  286. print->public.reference    = reference;
  287. print->public.jobtitle    = jobtitle;
  288.  
  289. message.header.action        = message_PRINTSAVE;
  290. message.header.size        = 256;
  291. message.data.print.filler[4]    = estsize;
  292. message.data.print.filetype    = filetype;
  293. message.header.yourref        = 0;        /* not a reply*/
  294. sprintf( message.data.print.filename, leafname);
  295. Wimp_SendMessage( event_SENDWANTACK, &message, 0, 0);
  296. print->message_ref = message.header.myref;
  297.  
  298. Print__ClaimMessages( print);
  299.  
  300. print->progress = print__progress_2;
  301.  
  302. return NOERROR;
  303. }
  304.  
  305.  
  306.  
  307.  
  308.  
  309.  
  310. static void    Print__ClaimMessages( print__block *print)
  311. {
  312. Event_Claim( event_USERMESSAGE, event_ANY, event_ANY, Print__MessageHandler, print);
  313. Event_Claim( event_USERMESSAGERECORDED, event_ANY, event_ANY, Print__MessageHandler, print);
  314. Event_Claim( event_ACK, event_ANY, event_ANY, Print__MessageHandler, print);
  315. }
  316.  
  317. static void    Print__ReleaseMessages( print__block *print)
  318. {
  319. Event_Release( event_USERMESSAGE, event_ANY, event_ANY, Print__MessageHandler, print);
  320. Event_Release( event_USERMESSAGERECORDED, event_ANY, event_ANY, Print__MessageHandler, print);
  321. Event_Release( event_ACK, event_ANY, event_ANY, Print__MessageHandler, print);
  322. }
  323.  
  324.  
  325.  
  326. static void    Print__Finish( 
  327.     print__block    *print, 
  328.     BOOL            releasemsgs, 
  329.     print_result    result
  330.     )
  331. {
  332. if ( print->resultfn)    print->resultfn( &print->public, result);
  333. if ( releasemsgs)    Print__ReleaseMessages( print);
  334. free( print);
  335. }
  336.  
  337.