home *** CD-ROM | disk | FTP | other *** search
/ Club Amiga de Montreal - CAM / CAM_CD_1.iso / files / 104.lha / textreader.c < prev    next >
C/C++ Source or Header  |  1980-07-10  |  16KB  |  750 lines

  1. /* TextReader by Oren Peli, Copyright (c) 1987 BazboSOFT! */
  2.  
  3. /*
  4.  *    Introduction:
  5.  *    
  6.  *        TextReader is, I believe, the most useful program I've written on
  7.  *            the Amiga and I am very proud of it.
  8.  *        
  9.  *        TextReader's purpose is to make editing within the CLI much easier,
  10.  *            and as far as I know, there isn't any other program of that kind
  11.  *            for the Amiga.
  12.  *        
  13.  *        Examples of where could TextReader make you life easier:
  14.  *        
  15.  *            1)    Right after finishing writing TextReader, I wanted to copy it
  16.  *                to my browsing/debugging/working CLI disk, only that
  17.  *                it was completely full.
  18.  *                
  19.  *            I dir'ed the C subdirectory and saw many files I never
  20.  *                use (lab, if, endif, else, etc.). So I wrote (from csh):
  21.  *            % rm
  22.  *                and with TextReader copied all the files names I wanted
  23.  *                to delete.
  24.  *                
  25.  *            2)    While looking at several Fish disks to see how useful and
  26.  *                debugged TextReader was, I've encounterred STEmualtor:
  27.  *                I cd'ed into it's directory (with TextReader, of
  28.  *                course) and 'Type'ed 'README'. Fish wrote in that file
  29.  *                that in order to run the STEmulator, it is necessary to
  30.  *                   write something like:
  31.  *                "assign STEmulator: AmigaLibDisk43:STEmulator",
  32.  *                so, with TextReader, I simply copied those instructions
  33.  *                instead of retyping then.
  34.  *        
  35.  *    Usage:
  36.  *    
  37.  *        It's very simple: run it (using the run command) and press the
  38.  *            left mouse button within the CLI window on a text, drag the
  39.  *            mouse and watch the results.
  40.  *        
  41.  *        To quit:    You have a menu: just press the right mouse button
  42.  *                and pick the Quit (and only) menu.
  43.  *    
  44.  *    
  45.  *        Note:    The menu will appear ONLY if the pointer is positioned
  46.  *            above the window's title bar.
  47.  *        
  48.  *    
  49.  *    If the right mouse button is pressed:
  50.  *    
  51.  *            If the pointer is positioned left of the cursor (but in the
  52.  *                same line) the program will generate BACKSPACE events.
  53.  *        
  54.  *            If the pointer is positioned right of the cursor (but in the
  55.  *                same line) the program will generate DEL keys events.
  56.  *        
  57.  *            If the pointer is positioned exactly over the cursor, the
  58.  *                program will echo your arguments.
  59.  *            
  60.  *            If the pointer is positioned under the current cursor line,
  61.  *                the program will generate a RETURN key event.
  62.  *                
  63.  *    Syntax:
  64.  *        RUN TextReader [string...]
  65.  *        
  66.  *        Note: For generating Return key event, use '\n'
  67.  *        
  68.  *    Examples:
  69.  *        
  70.  *        RUN TextReader
  71.  *        RUN TextReader "Cd df1:\nDir opt a\n"
  72.  *        RUN TextReader sys:
  73.  *        RUN TextReader NewCLI\n
  74.  *        
  75.  *    Problems list:
  76.  *        1)    The program won't recognize alt characters.
  77.  *        2)    The program won't recognize any text written with foreground
  78.  *                color other then 1 and/or background color other then 0.
  79.  *        3)    The program won't recognize any text written in any other
  80.  *                style then normal.
  81.  *        4)    The program won't recognize any text written with font
  82.  *                which its size is not 8x8 (the font must also be
  83.  *                a fixed with font (e.g. not proportional) ).
  84.  *        5)    After changing the font (using 'font' for example) of the cli,
  85.  *                you MUST quit from TextReader and re-run it.
  86.  *    
  87.  *    All in all, TextReader is an extremely useful utility and should be called
  88.  *        from everyone's startup-sequence.
  89.  *    
  90.  *    Bug reports, suggestions, etc. can be sent to me at the following address:
  91.  *        
  92.  *        Oren Peli
  93.  *        Shkediya 13
  94.  *        Ramat-Gan    52-546
  95.  *        ISRAEL
  96.  *        
  97.  *    ..or, if you want to chat with me over the phone, you can call: 03-7514475.
  98.  *    
  99.  *    
  100.  *    You may not immediately realize how powerful TextReader really is,
  101.  *        after doing so, please consider sending me a donation
  102.  *        ($20 seems like a nice round number), although TextReader is NOT
  103.  *        a Sharewere program but a public domain.
  104.  *
  105.  *    For every $100 dollars I receive, I will fix a problem from
  106.  *        the above list.
  107.  *    
  108.  *    ENJOY!
  109.  */
  110.  
  111. #include <intuition/intuitionbase.h>    /* Added by Adams Douglas */
  112. #include <devices/conunit.h>
  113. #include <devices/input.h>
  114. #include <exec/memory.h>
  115. #include <graphics/gfxbase.h>
  116. #include <libraries/dosextens.h>
  117.  
  118. extern void *AllocMem();
  119.  
  120. extern PLANEPTR AllocRaster();
  121.  
  122. struct IntuitionBase *IntuitionBase = NULL;
  123. struct GfxBase *GfxBase = NULL;
  124.  
  125. extern void *OpenLibrary();
  126.  
  127. extern void *CreateStdIO();
  128.  
  129. extern long findWindow();
  130.  
  131. struct ConUnit *conUnit = NULL;
  132.  
  133. struct Window *conWindow = NULL;
  134.  
  135. void *CreatePort() , *FindPort();
  136.  
  137. struct Process *FindTask();
  138.  
  139. struct IntuiMessage *GetMsg();
  140.  
  141. struct RastPort dummy_rastport , *trp = &dummy_rastport;
  142. struct BitMap dummy_bitmap , *tbm = &dummy_bitmap;
  143.  
  144. struct RastPort dummy_rastport2 , *crp = &dummy_rastport2;
  145. struct BitMap dummy_bitmap2 , *cbm = &dummy_bitmap2;
  146.  
  147.  
  148. struct IntuiText ItemText = { 3 , 1 , JAM1 , 1 , 1 , NULL , (STRPTR) "Quit TextReader"
  149. , NULL };
  150.  
  151. struct MenuItem MenuItem = { NULL , 0 , 0 , 121 , 10 , ITEMTEXT | ITEMENABLED |
  152. HIGHCOMP, 0, (APTR) &ItemText , NULL , NULL , NULL , 0xFFFF };
  153.  
  154. struct Menu Menu = { NULL , 0 , 0 , 121 , 0 , MENUENABLED , " Quit" , &MenuItem };
  155.  
  156. struct chr_data
  157. {
  158.     char chr;
  159.     char raw_data;
  160.     char is_shifted;
  161.     PLANEPTR pln;
  162. };
  163.  
  164. struct chr_data chrs[] =
  165. {
  166.     {    ' '    ,    0x40    ,    0    } ,
  167.     {    'a'    ,    0x20    ,    0    } ,
  168.     {    'b'    ,    0x35    ,    0    } ,
  169.     {    'c'    ,    0x33    ,    0    } ,
  170.     {    'd'    ,    0x22    ,    0    } ,
  171.     {    'e'    ,    0x12    ,    0    } ,
  172.     {    'f'    ,    0x23    ,    0    } ,
  173.     {    'g'    ,    0x24    ,    0    } ,
  174.     {    'h'    ,    0x25    ,    0    } ,
  175.     {    'i'    ,    0x17    ,    0    } ,
  176.     {    'j'    ,    0x26    ,    0    } ,
  177.     {    'k'    ,    0x27    ,    0    } ,
  178.     {    'l'    ,    0x28    ,    0    } ,
  179.     {    'm'    ,    0x37    ,    0    } ,
  180.     {    'n'    ,    0x36    ,    0    } ,
  181.     {    'o'    ,    0x18    ,    0    } ,
  182.     {    'p'    ,    0x19    ,    0    } ,
  183.     {    'q'    ,    0x10    ,    0    } ,
  184.     {    'r'    ,    0x13    ,    0    } ,
  185.     {    's'    ,    0x21    ,    0    } ,
  186.     {    't'    ,    0x14    ,    0    } ,
  187.     {    'u'    ,    0x16    ,    0    } ,
  188.     {    'v'    ,    0x34    ,    0    } ,
  189.     {    'w'    ,    0x11    ,    0    } ,
  190.     {    'x'    ,    0x32    ,    0    } ,
  191.     {    'y'    ,    0x15    ,    0    } ,
  192.     {    'z'    ,    0x31    ,    0    } ,
  193.     {    '0'    ,    0x0a    ,    0    } ,
  194.     {    '1'    ,    0x01    ,    0    } ,
  195.     {    '2'    ,    0x02    ,    0    } ,
  196.     {    '3'    ,    0x03    ,    0    } ,
  197.     {    '4'    ,    0x04    ,    0    } ,
  198.     {    '5'    ,    0x05    ,    0    } ,
  199.     {    '6'    ,    0x06    ,    0    } ,
  200.     {    '7'    ,    0x07    ,    0    } ,
  201.     {    '8'    ,    0x08    ,    0    } ,
  202.     {    '9'    ,    0x09    ,    0    } ,
  203.     {    '-'    ,    0x0b    ,    0    } ,
  204.     {    '='    ,    0x0c    ,    0    } ,
  205.     {    '\\'    ,    0x0d    ,    0    } ,
  206.     {    '['    ,    0x1a    ,    0    } ,
  207.     {    ']'    ,    0x1b    ,    0    } ,
  208.     {    ';'    ,    0x29    ,    0    } ,
  209.     {    '\''    ,    0x2a    ,    0    } ,
  210.     {    ','    ,    0x38    ,    0    } ,
  211.     {    '.'    ,    0x39    ,    0    } ,
  212.     {    '/'    ,    0x3a    ,    0    } ,
  213.     {    '`'    ,    0x00    ,    0    } ,
  214.     {    'A'    ,    0x20    ,    1    } ,
  215.     {    'B'    ,    0x35    ,    1    } ,
  216.     {    'C'    ,    0x33    ,    1    } ,
  217.     {    'D'    ,    0x22    ,    1    } ,
  218.     {    'E'    ,    0x12    ,    1    } ,
  219.     {    'F'    ,    0x23    ,    1    } ,
  220.     {    'G'    ,    0x24    ,    1    } ,
  221.     {    'H'    ,    0x25    ,    1    } ,
  222.     {    'I'    ,    0x17    ,    1    } ,
  223.     {    'J'    ,    0x26    ,    1    } ,
  224.     {    'K'    ,    0x27    ,    1    } ,
  225.     {    'L'    ,    0x28    ,    1    } ,
  226.     {    'M'    ,    0x37    ,    1    } ,
  227.     {    'N'    ,    0x36    ,    1    } ,
  228.     {    'O'    ,    0x18    ,    1    } ,
  229.     {    'P'    ,    0x19    ,    1    } ,
  230.     {    'Q'    ,    0x10    ,    1    } ,
  231.     {    'R'    ,    0x13    ,    1    } ,
  232.     {    'S'    ,    0x21    ,    1    } ,
  233.     {    'T'    ,    0x14    ,    1    } ,
  234.     {    'U'    ,    0x16    ,    1    } ,
  235.     {    'V'    ,    0x34    ,    1    } ,
  236.     {    'W'    ,    0x11    ,    1    } ,
  237.     {    'X'    ,    0x32    ,    1    } ,
  238.     {    'Y'    ,    0x15    ,    1    } ,
  239.     {    'Z'    ,    0x31    ,    1    } ,
  240.     {    '!'    ,    0x01    ,    1    } ,
  241.     {    '@'    ,    0x02    ,    1    } ,
  242.     {    '#'    ,    0x03    ,    1    } ,
  243.     {    '$'    ,    0x04    ,    1    } ,
  244.     {    '%'    ,    0x05    ,    1    } ,
  245.     {    '^'    ,    0x06    ,    1    } ,
  246.     {    '&'    ,    0x07    ,    1    } ,
  247.     {    '*'    ,    0x08    ,    1    } ,
  248.     {    '('    ,    0x09    ,    1    } ,
  249.     {    ')'    ,    0x0a    ,    1    } ,
  250.     {    '_'    ,    0x0b    ,    1    } ,
  251.     {    '+'    ,    0x0c    ,    1    } ,
  252.     {    '|'    ,    0x0d    ,    1    } ,
  253.     {    '{'    ,    0x1a    ,    1    } ,
  254.     {    '}'    ,    0x1b    ,    1    } ,
  255.     {    ':'    ,    0x29    ,    1    } ,
  256.     {    '"'    ,    0x2a    ,    1    } ,
  257.     {    '<'    ,    0x38    ,    1    } ,
  258.     {    '>'    ,    0x39    ,    1    } ,
  259.     {    '?'    ,    0x3a    ,    1    } ,
  260.     {    '~'    ,    0x00    ,    1    } ,
  261.     {    -1    ,    -1    ,    -1    }
  262. };
  263.  
  264. struct MsgPort *port = NULL;
  265. struct IOStdReq *req = NULL;
  266.  
  267. long errdev = 0;
  268.  
  269. int num_of_chrs;
  270.  
  271. struct InputEvent ie;
  272.  
  273. int really_open_window = 0;
  274.  
  275. do_args(c , v)
  276. register int c;
  277. register char *v[];
  278. {
  279.     register int i , j , k , s;
  280.     register char chr;
  281.     
  282.     for (i = 1 ; i < c ; i++)
  283.     {
  284.         s = strlen(v[i]);
  285.  
  286.         for (j = 0 ; j < s ; j++)
  287.         {
  288.             if (v[i][j] == '\\' && v[i][j + 1] == 'n')
  289.             {
  290.                 ie.ie_Qualifier = NULL;
  291.  
  292.                 ie.ie_Code = 0x44;
  293.  
  294.                 DoIO(req);
  295.  
  296.                 ie.ie_Code = 0x44 | 0x80;
  297.  
  298.                 DoIO(req);
  299.  
  300.                 j += 2;
  301.             }
  302.  
  303.             chr = v[i][j];
  304.  
  305.             for (k = 0 ; k != num_of_chrs ; k++)
  306.                 if (chrs[k].chr == chr)
  307.                 {
  308.                     fake_raw_key_event(k);
  309.                     
  310.                     break;
  311.                 }
  312.         }
  313.     }
  314. }
  315.  
  316. fake_raw_key_event(c)
  317. register char c;
  318. {
  319.     ie.ie_Qualifier = chrs[c].is_shifted ? IEQUALIFIER_LSHIFT : NULL;
  320.     ie.ie_Code = chrs[c].raw_data;
  321.  
  322.     DoIO(req);
  323.  
  324.     ie.ie_Code |= 0x80;
  325.  
  326.     DoIO(req);
  327. }
  328.  
  329. the_same()
  330. {
  331.     register int i;
  332.  
  333.     register PLANEPTR ptr1 , ptr2;
  334.  
  335.     ptr1 = cbm->Planes[0];
  336.     ptr2 = tbm->Planes[0];
  337.  
  338.     for (i = 0 ; i != 16 ; i += 2)
  339.         if (ptr1[i] != ptr2[i])
  340.             return(0);
  341.  
  342.     return(1);
  343. }
  344.  
  345. identify_char()
  346. {
  347.     register int c;
  348.  
  349.     for (c = 0 ; c != num_of_chrs ; c++)
  350.     {
  351.         cbm->Planes[0] = chrs[c].pln;
  352.  
  353.         if (the_same() )
  354.             return(c);
  355.     }
  356.  
  357.     return(-1);
  358. }
  359.  
  360. convert_char(x , y)
  361. register int x , y;
  362. {
  363.     register int rx , ry;
  364.  
  365.     register int c;
  366.  
  367.     rx = x - conUnit->cu_XROrigin;
  368.     ry = y - conUnit->cu_YROrigin;
  369.  
  370.     rx &= ~7;
  371.     ry &= ~7;
  372.  
  373.     rx += conUnit->cu_XROrigin;
  374.     ry += conUnit->cu_YROrigin;
  375.  
  376.     ClipBlit(conWindow->RPort , (long) rx , (long) ry , trp , 0L , 0L , 8L , 8L ,
  377.                                         0xC0L);
  378.  
  379.     if ( (c = identify_char() ) != -1)
  380.         fake_raw_key_event(c);
  381. }
  382.  
  383. main(argc , argv)
  384. int argc;
  385. char *argv[];
  386. {
  387.     register struct Window *win;
  388.     register struct IntuiMessage *msg;
  389.     register int x , y , code , qua;
  390.     register long class;
  391.     register int pressed = 0;
  392.     register int rx , ry;
  393.     register int prx = -1111 , fy , px = -1111 , maxx = -1111;
  394.     register int i;
  395.     register char buf[2];
  396.     register long bl;
  397.     register char string_buffer[50];
  398.  
  399.     puts("TextReader, by Oren Peli, Copyright (C) 1987 BazboSOFT!");
  400.  
  401.     for (i = 0 ; chrs[i].raw_data != -1 ; i++)
  402.         chrs[i].pln = NULL;
  403.  
  404.     num_of_chrs = i - 1;
  405.  
  406.     if (NOT (IntuitionBase = (struct IntuitionBase *)
  407.                     OpenLibrary("intuition.library" , 33L) ) )
  408.         bye();
  409.  
  410.     if (NOT findWindow() )
  411.         bye();
  412.  
  413.     win = conWindow;
  414.  
  415.     sprintf(string_buffer , "TextReader's port (win:%lx)" , win);
  416.  
  417.     if (FindPort(string_buffer) )
  418.     {
  419.         puts("But you have already ran TextReader from this window!");
  420.  
  421.         bye();
  422.     }
  423.  
  424.     if (NOT (port = CreatePort(string_buffer , 0L) ) )
  425.         bye();
  426.  
  427.     if (NOT (req = CreateStdIO(port) ) )
  428.         bye();
  429.  
  430.     if (errdev = OpenDevice("input.device" , 0L , req , 0L) )
  431.         bye();
  432.  
  433.     if (NOT (GfxBase = (struct GfxBase *) OpenLibrary("graphics.library" , 33L) ) )
  434.         bye();
  435.  
  436.     InitRastPort(trp);
  437.     InitRastPort(crp);
  438.  
  439.     InitBitMap(tbm , 1L , 8L , 8L);
  440.     InitBitMap(cbm , 1L , 8L , 8L);
  441.  
  442.     trp->BitMap = tbm;
  443.     crp->BitMap = cbm;
  444.  
  445.     if (NOT (tbm->Planes[0] = AllocRaster(8L , 8L) ) )
  446.         bye();
  447.  
  448.     SetAPen(trp , 0L);
  449.  
  450.     RectFill(trp , 0L , 0L , 8L , 8L);
  451.  
  452.     buf[1] = 0;
  453.  
  454.     SetAPen(crp , 1L);
  455.     SetDrMd(crp , JAM2);
  456.  
  457.     bl = GfxBase->DefaultFont->tf_Baseline;
  458.  
  459.     for (i = 0 ; i != num_of_chrs ; i++)
  460.     {
  461.         cbm->Planes[0] = chrs[i].pln = AllocRaster(8L , 8L);
  462.  
  463.         if (NOT chrs[i].pln)
  464.             bye();
  465.  
  466.         Move(crp , 0L , bl);
  467.  
  468.         buf[0] = chrs[i].chr;
  469.  
  470.         Text(crp , buf , 1L);
  471.     }
  472.  
  473.     req->io_Command = IND_WRITEEVENT;
  474.     req->io_Flags = 0;
  475.     req->io_Length = (long) sizeof(struct InputEvent);
  476.     req->io_Data = (void *) &ie;
  477.  
  478.     ie.ie_NextEvent = NULL;
  479.     ie.ie_Class = IECLASS_RAWKEY;
  480.     ie.ie_TimeStamp.tv_secs = 0;
  481.     ie.ie_TimeStamp.tv_micro = 0;
  482.     ie.ie_X = 0;
  483.     ie.ie_Y = 0;
  484.  
  485.     ModifyIDCMP(win , MOUSEBUTTONS | MOUSEMOVE | MENUPICK);
  486.  
  487.     ReportMouse(TRUE , win);
  488.  
  489.     SetMenuStrip(win , &Menu);
  490.  
  491.     while (msg = GetMsg(win->UserPort) )
  492.         ReplyMsg(msg);
  493.  
  494.  
  495.     really_open_window = 1;
  496.  
  497. loop:
  498.     WaitPort(win->UserPort);
  499.  
  500.     msg = GetMsg(win->UserPort);
  501.  
  502.     class = msg->Class;
  503.     code = msg->Code;
  504.     x = msg->MouseX;
  505.     y = msg->MouseY;
  506.  
  507.     ReplyMsg(msg);
  508.  
  509.     Forbid();
  510.  
  511.     if (y < 10)
  512.         win->Flags &= ~RMBTRAP;
  513.     else
  514.         win->Flags |= RMBTRAP;
  515.  
  516.     Permit();
  517.  
  518.     if (class == MENUPICK && code != MENUNULL)
  519.         bye();
  520.  
  521.     else if (class == MOUSEBUTTONS)
  522.     {
  523.         if (code == SELECTDOWN)
  524.         {
  525.             ry = ( (fy = y) - conUnit->cu_YROrigin) / 8;
  526.             pressed = 1;
  527.         }
  528.  
  529.         else if (code == SELECTUP)
  530.         {
  531.             prx = -1111;
  532.             px = -1111;
  533.             maxx = -1111;
  534.  
  535.             pressed = 0;
  536.         }
  537.  
  538.         else if (code == MENUDOWN)
  539.         {
  540.             rx = (x - conUnit->cu_XROrigin) / 8;
  541.             ry = (y - conUnit->cu_YROrigin) / 8;
  542.  
  543.             ie.ie_Qualifier = NULL;
  544.  
  545.             if (ry > conUnit->cu_YCCP)
  546.             {
  547.                 ie.ie_Code = 0x44;
  548.  
  549.                 DoIO(req);
  550.  
  551.                 ie.ie_Code = 0x44 | 0x80;
  552.  
  553.                 DoIO(req);
  554.             }
  555.  
  556.             else if (ry == conUnit->cu_YCCP)
  557.             {
  558.                 if (rx > conUnit->cu_XCCP)
  559.                 {
  560.                     for (i = rx - conUnit->cu_XCCP + 1 ; i ; i--)
  561.                     {
  562.                         ie.ie_Code = 0x46;
  563.  
  564.                         DoIO(req);
  565.  
  566.                         ie.ie_Code = 0x46 | 0x80;
  567.  
  568.                         DoIO(req);
  569.                     }
  570.                 }
  571.  
  572.                 else if (rx < conUnit->cu_XCCP)
  573.                 {
  574.                     for (i = conUnit->cu_XCCP - rx ; i ; i--)
  575.                     {
  576.                         ie.ie_Code = 0x41;
  577.  
  578.                         DoIO(req);
  579.  
  580.                         ie.ie_Code = 0x41 | 0x80;
  581.  
  582.                         DoIO(req);
  583.                     }
  584.                 }
  585.  
  586.                 else if (rx == conUnit->cu_XCCP)
  587.                     do_args(argc , argv);
  588.             }
  589.  
  590.             prx = -1111;
  591.             px = -1111;
  592.             maxx = -1111;
  593.  
  594.             pressed = 0;
  595.         }
  596.     }
  597.  
  598.     if (pressed && x >= conUnit->cu_XROrigin && y >= conUnit->cu_YROrigin && x <
  599.                 conUnit->cu_XRExtant && y < conUnit->cu_YRExtant)
  600.     {
  601.         rx = (x - conUnit->cu_XROrigin) / 8;
  602.  
  603.         if (rx != prx && rx > maxx)
  604.         {
  605.             maxx = rx;
  606.  
  607.             if (rx > prx && rx - prx > 1 && prx != -1111)
  608.             {
  609.                 for (i = rx - prx + 1 , x = px + 8 ; i && x <
  610.                         conUnit->cu_XRExtant ; x += 8 , i--)
  611.                     convert_char(x , fy);
  612.                 
  613.                 x -= 8;
  614.             }
  615.  
  616.             else
  617.                 convert_char(x , fy);
  618.  
  619.             rx = (x - conUnit->cu_XROrigin) / 8;
  620.  
  621.             if (rx > maxx)
  622.                 maxx = rx;
  623.  
  624.             prx = rx;
  625.  
  626.             px = x;
  627.         }
  628.     }
  629.  
  630.     goto loop;
  631.  
  632.     bye();
  633. }
  634.  
  635. bye()
  636. {
  637.     register int i;
  638.  
  639.     for (i = 0 ; i != num_of_chrs ; i++)
  640.         if (chrs[i].pln)
  641.             FreeRaster(chrs[i].pln , 8L , 8L);
  642.  
  643.     if (tbm->Planes[0])
  644.         FreeRaster(tbm->Planes[0] , 8L , 8L);
  645.  
  646.     if (conWindow && really_open_window)
  647.     {
  648.         Forbid();
  649.  
  650.         conWindow->Flags &= ~RMBTRAP;
  651.  
  652.         Permit();
  653.  
  654.         ClearMenuStrip(conWindow);
  655.  
  656.         ReportMouse(FALSE , conWindow);
  657.  
  658.         ModifyIDCMP(conWindow , NULL);
  659.     }
  660.  
  661.     if (IntuitionBase)
  662.         CloseLibrary(IntuitionBase);
  663.  
  664.     if (GfxBase)
  665.         CloseLibrary(GfxBase);
  666.  
  667.     if (NOT errdev && req)
  668.         CloseDevice(req);
  669.  
  670.     if (req)
  671.         DeleteStdIO(req);
  672.  
  673.     if (port)
  674.         DeletePort(port);
  675.  
  676.     exit(0);
  677. }
  678.  
  679. extern long sendpkt();
  680.  
  681. LONG findWindow() /* inits conWindow and conUnit (global vars) */
  682.    {
  683.    register struct InfoData *id;
  684.     register    struct MsgPort  *conid;
  685.     register    struct Process  *me;
  686.     register   LONG myargs[8] ,nargs, res1;
  687.  
  688.    /* Alloc to insure longword alignment */
  689.    id = (struct InfoData *)AllocMem( (long) sizeof(struct InfoData),
  690.                                        MEMF_PUBLIC|MEMF_CLEAR);
  691.    if(! id) return(0);
  692.    me = (struct Process *) FindTask(NULL);
  693.    conid = (struct MsgPort *) me->pr_ConsoleTask;
  694.  
  695.    myargs[0]=((ULONG)id) >> 2;
  696.    nargs = 1;
  697.    res1 = (LONG)sendpkt(conid,ACTION_DISK_INFO,myargs,nargs);
  698.    conWindow = (struct Window *)id->id_VolumeNode;
  699.    conUnit = (struct ConUnit *)
  700.                  ((struct IOStdReq *)id->id_InUse)->io_Unit;
  701.    FreeMem(id, (long) sizeof(struct InfoData));
  702.    return(res1);
  703. }
  704.  
  705.  
  706. LONG sendpkt(pid,action,args,nargs)
  707. register struct MsgPort *pid;  /* process indentifier ... (handlers message port ) */
  708. register LONG action,          /* packet type ... (what you want handler to do )   */
  709.      args[],          /* a pointer to a argument list */
  710.      nargs;           /* number of arguments in list  */
  711.    {
  712.     register    struct MsgPort        *replyport;
  713.    struct StandardPacket *packet;
  714.  
  715.     register    LONG  count, *pargs, res1;
  716.  
  717.    replyport = (struct MsgPort *) CreatePort( (long) NULL, (long) 0);
  718.    if(!replyport) return( (long) NULL);
  719.  
  720.    packet = (struct StandardPacket *) 
  721.       AllocMem((long)sizeof(struct StandardPacket),MEMF_PUBLIC|MEMF_CLEAR);
  722.    if(!packet) 
  723.       {
  724.       DeletePort(replyport);
  725.       return(NULL);
  726.       }
  727.  
  728.    packet->sp_Msg.mn_Node.ln_Name = (char *)&(packet->sp_Pkt);
  729.    packet->sp_Pkt.dp_Link         = &(packet->sp_Msg);
  730.    packet->sp_Pkt.dp_Port         = replyport;
  731.    packet->sp_Pkt.dp_Type         = action;
  732.  
  733.    /* copy the args into the packet */
  734.    pargs = &(packet->sp_Pkt.dp_Arg1);       /* address of first argument */
  735.    for(count=0;count < nargs;count++) 
  736.       pargs[count]=args[count];
  737.  
  738.    PutMsg(pid,packet); /* send packet */
  739.  
  740.    WaitPort(replyport);
  741.    GetMsg(replyport); 
  742.  
  743.    res1 = packet->sp_Pkt.dp_Res1;
  744.  
  745.    FreeMem(packet,(long)sizeof(struct StandardPacket));
  746.    DeletePort(replyport); 
  747.  
  748.    return(res1);
  749. }
  750.