home *** CD-ROM | disk | FTP | other *** search
/ BCI NET / BCI NET Dec 94.iso / archives / telecomm / terms / term-4.1-source.lha / Extras / Source / term-Source.lha / termMarker.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-08-07  |  16.5 KB  |  755 lines

  1. /*
  2. **    termMarker.c
  3. **
  4. **    Text block marker routines
  5. **
  6. **    Copyright © 1990-1994 by Olaf `Olsen' Barthel
  7. **        All Rights Reserved
  8. */
  9.  
  10. #include "termGlobal.h"
  11.  
  12.     /* BM_Draw():
  13.      *
  14.      *    Redraw or remove marked regions.
  15.      */
  16.  
  17. VOID __regargs
  18. BM_Draw(struct BlockMarker *Marker,VOID (*Select)(struct BlockMarker *Marker,LONG Left,LONG Top,LONG Width,LONG Height))
  19. {
  20.         /* Is the first line the same as the last line? If so,
  21.          * continue and mark only single characters. Else,
  22.          * determine first line and column to mark and last
  23.          * line and last column.
  24.          */
  25.  
  26.     if(Marker -> FirstLine != Marker -> LastLine)
  27.     {
  28.         LONG    First    = Marker -> FirstLine - Marker -> Top,
  29.             Last    = Marker -> LastLine  - Marker -> Top,
  30.             Lines;
  31.  
  32.             /* Is the first line visible? If so, mark it. */
  33.  
  34.         if(First >= 0)
  35.             (*Select)(Marker,Marker -> FirstColumn,First,Marker -> Width - Marker -> FirstColumn,1);
  36.         else
  37.         {
  38.             (*Select)(Marker,0,0,Marker -> Width,1);
  39.  
  40.             First = 0;
  41.         }
  42.  
  43.             /* Is the last line visible? If so, mark it. */
  44.  
  45.         if(Last >= 0 && Last < Marker -> Height)
  46.             (*Select)(Marker,0,Last,Marker -> LastColumn,1);
  47.         else
  48.             Last = Marker -> Height;
  49.  
  50.             /* Determine the number of lines the selection spans. */
  51.  
  52.         if((Lines = Last - First - 1) > 0)
  53.             (*Select)(Marker,0,First + 1,Marker -> Width,Lines);
  54.     }
  55.     else
  56.     {
  57.             /* Is the first column different from the last column? */
  58.  
  59.         if(Marker -> FirstColumn != Marker -> LastColumn)
  60.         {
  61.                 /* Is the line visible? If so, mark it. */
  62.  
  63.             if(Marker -> Top <= Marker -> LastLine && Marker -> LastLine < Marker -> Top + Marker -> Height)
  64.                 (*Select)(Marker,Marker -> FirstColumn,Marker -> FirstLine - Marker -> Top,Marker -> LastColumn - Marker -> FirstColumn,1);
  65.         }
  66.     }
  67. }
  68.  
  69.     /* BM_ClearMark(struct BlockMarker *Marker):
  70.      *
  71.      *    Free block marker memory.
  72.      */
  73.  
  74. VOID __regargs
  75. BM_ClearMark(struct BlockMarker *Marker)
  76. {
  77.     BM_Draw(Marker,Marker -> Unselect);
  78.  
  79.     FreeVecPooled(Marker);
  80. }
  81.  
  82.     /* BM_SetMark():
  83.      *
  84.      *    Create block marker structure.
  85.      */
  86.  
  87. struct BlockMarker * __regargs
  88. BM_SetMark(APTR Object,VPTR Select,VPTR Unselect,LONG Width,LONG Height,LONG LeftEdge,LONG TopEdge,LONG Top,LONG Lines,LONG X,LONG Y,WORD TextFontWidth,WORD TextFontHeight)
  89. {
  90.     if(Height && Lines)
  91.     {
  92.         struct BlockMarker *Marker;
  93.  
  94.             /* Allocate marker buffer. */
  95.  
  96.         if(Marker = (struct BlockMarker *)AllocVecPooled(sizeof(struct BlockMarker),MEMF_ANY | MEMF_CLEAR))
  97.         {
  98.                 /* Fill in the object or canvas, usually a RastPort. */
  99.  
  100.             Marker -> Object    = Object;
  101.  
  102.                 /* Fill in the canvas left and top edge. */
  103.  
  104.             Marker -> LeftEdge    = LeftEdge;
  105.             Marker -> TopEdge    = TopEdge;
  106.  
  107.                 /* Fill in the select and unselect routines. */
  108.  
  109.             Marker -> Select    = Select;
  110.             Marker -> Unselect    = Unselect;
  111.  
  112.                 /* Fill in current display window top and number of
  113.                  * lines in the buffer.
  114.                  */
  115.  
  116.             Marker -> Top        = Top;
  117.             Marker -> Lines        = Lines;
  118.  
  119.                 /* Fill in width and height of the display window. */
  120.  
  121.             Marker -> Width        = Width;
  122.             Marker -> Height    = Height;
  123.  
  124.                 /* Fill in the marker anchor point. */
  125.  
  126.             Marker -> FirstColumn    = X;
  127.             Marker -> LastColumn    = X;
  128.             Marker -> FirstLine    = Y + Top;
  129.             Marker -> LastLine    = Y + Top;
  130.  
  131.                 /* Fill in current mouse position. */
  132.  
  133.             Marker -> LastX        = X;
  134.             Marker -> LastY        = Y;
  135.  
  136.             Marker -> OriginX    = X;
  137.             Marker -> OriginY    = Y + Top;
  138.  
  139.                 /* Remember text font dimensions. */
  140.  
  141.             Marker -> TextFontWidth    = TextFontWidth;
  142.             Marker -> TextFontHeight= TextFontHeight;
  143.  
  144.             Marker -> WriteMask    = ((struct RastPort *)Object) -> Mask;
  145.         }
  146.  
  147.             /* Return marker buffer. */
  148.  
  149.         return(Marker);
  150.     }
  151.     else
  152.         return(NULL);
  153. }
  154.  
  155.     /* BM_ExtendMark(struct BlockMarker *Marker,LONG X,LONG Y,LONG Delta):
  156.      *
  157.      *    Extend current block marker. This routine was
  158.      *    first written by me, but Martin Berndt rewrote it
  159.      *    after we both realised that it would not work
  160.      *    properly.
  161.      */
  162.  
  163. VOID __regargs
  164. BM_ExtendMark(struct BlockMarker *Marker,LONG X,LONG Y,LONG Delta)
  165. {
  166.     if(Marker -> LastX != X || Marker -> LastY != Y)
  167.     {
  168.         LONG    OldCharPos,NewCharPos,
  169.             CharStart,CharEnd,
  170.             CharOrigin,
  171.             OriginY,
  172.             Lines;
  173.         BYTE    Crossed;
  174.  
  175.             OriginY = Marker -> OriginY - Marker -> Top;
  176.  
  177.  
  178.             /* Deal with illegal X position. */
  179.  
  180.         if(X < 0)
  181.             X = 0;
  182.  
  183.         if(X > Marker -> Width)
  184.             X = Marker -> Width;
  185.  
  186.             /* Deal with illegal Y position. */
  187.  
  188.         if(Y < 0)
  189.             Y = 0;
  190.  
  191.         if(Y >= Marker -> Height)
  192.             Y = Marker -> Height - 1;
  193.  
  194.         if(Y + Marker -> Top >= Marker -> Lines)
  195.             Y = Marker -> Lines - Marker -> Top - 1;
  196.  
  197.             /* Is the Y position larger than the last line? If so,
  198.              * truncate it.
  199.              */
  200.  
  201.         if(Y > Marker -> Lines - Marker -> Top)
  202.             Y -= Marker -> Lines - Marker -> Top;
  203.  
  204.             /* Select the text. */
  205.  
  206.         OldCharPos    = (Marker -> LastY + Marker -> Top) * Marker -> Width + Marker -> LastX;
  207.         NewCharPos    = (Y + Marker -> Top) * Marker -> Width + X;
  208.  
  209.         CharStart    = Marker -> FirstLine * Marker -> Width + Marker -> FirstColumn;
  210.         CharEnd        = Marker -> LastLine * Marker -> Width + Marker -> LastColumn;
  211.  
  212.         CharOrigin    = Marker -> OriginY * Marker -> Width + Marker -> OriginX;
  213.  
  214.         Crossed        = (OldCharPos < CharOrigin) ^ (NewCharPos < CharOrigin);
  215.  
  216.         if(NewCharPos > OldCharPos)
  217.         {
  218.             if(Delta && Y < OriginY)
  219.                 (*Marker -> Select)(Marker,0,Y,Marker -> Width,1);
  220.  
  221.             if(Crossed)
  222.             {
  223.                 if((Lines = OriginY - Marker -> LastY - 1) >= 0)
  224.                 {
  225.                     (*Marker -> Unselect)(Marker,Marker -> LastX,Marker -> LastY,Marker -> Width - Marker -> LastX,1);
  226.  
  227.                     if(Lines > 0)
  228.                         (*Marker -> Unselect)(Marker,0,Marker -> LastY + 1,Marker -> Width,Lines);
  229.  
  230.                     if(Marker -> OriginX)
  231.                         (*Marker -> Unselect)(Marker,0,OriginY,Marker -> OriginX,1);
  232.                 }
  233.                 else
  234.                 {
  235.                     if(Delta)
  236.                         (*Marker -> Unselect)(Marker,0,OriginY,Marker -> LastX,1);
  237.                     else
  238.                         (*Marker -> Unselect)(Marker,Marker -> LastX,OriginY,Marker -> OriginX - Marker -> LastX,1);
  239.                 }
  240.  
  241.                 Marker -> FirstColumn    = Marker -> OriginX;
  242.                 Marker -> FirstLine     = Marker -> OriginY;
  243.  
  244.                 Marker -> LastX        = Marker -> OriginX;
  245.                 Marker -> LastY        = OriginY;
  246.             }
  247.             else
  248.             {
  249.                 if(OldCharPos < CharOrigin)
  250.                 {
  251.                     if((Lines = Y - Marker -> LastY - 1) >= 0)
  252.                     {
  253.                         (*Marker -> Unselect)(Marker,Marker -> LastX,Marker -> LastY,Marker -> Width - Marker -> LastX,1);
  254.  
  255.                         if(Lines > 0)
  256.                             (*Marker -> Unselect)(Marker,0,Marker -> LastY + 1,Marker -> Width,Lines);
  257.  
  258.                         (*Marker -> Unselect)(Marker,0,Y,X,1);
  259.                     }
  260.                     else
  261.                     {
  262.                         if(Delta)
  263.                             (*Marker -> Unselect)(Marker,0,Y,X,1);
  264.                         else
  265.                             (*Marker -> Unselect)(Marker,Marker -> LastX,Y,X - Marker -> LastX,1);
  266.                     }
  267.  
  268.                     Marker -> FirstColumn    = X;
  269.                     Marker -> FirstLine    = Y + Marker -> Top;
  270.                 }
  271.             }
  272.  
  273.             if(NewCharPos > CharEnd)
  274.             {
  275.                 if((Lines = Y - Marker -> LastY - 1) >= 0)
  276.                 {
  277.                     (*Marker -> Select)(Marker,Marker -> LastX,Marker -> LastY,Marker -> Width - Marker -> LastX,1);
  278.  
  279.                     if(Lines > 0)
  280.                         (*Marker -> Select)(Marker,0,Marker -> LastY + 1,Marker -> Width,Lines);
  281.  
  282.                     (*Marker -> Select)(Marker,0,Y,X,1);
  283.                 }
  284.                 else
  285.                 {
  286.                     if(Delta)
  287.                         (*Marker -> Select)(Marker,0,Y,X,1);
  288.                     else
  289.                         (*Marker -> Select)(Marker,Marker -> LastX,Y,X - Marker -> LastX,1);
  290.                 }
  291.  
  292.                 Marker -> LastColumn    = X;
  293.                 Marker -> LastLine    = Y + Marker -> Top;
  294.             }
  295.         }
  296.         else
  297.         {
  298.             if(Delta && Y > OriginY)
  299.                 (*Marker -> Select)(Marker,0,Y,Marker -> Width,1);
  300.  
  301.             if(Crossed)
  302.             {
  303.                 if((Lines = Marker -> LastY - OriginY - 1) >= 0)
  304.                 {
  305.                     (*Marker -> Unselect)(Marker,0,Marker -> LastY,Marker -> LastX,1);
  306.  
  307.                     if(Lines > 0)
  308.                         (*Marker -> Unselect)(Marker,0,OriginY + 1,Marker -> Width,Lines);
  309.  
  310.                     (*Marker -> Unselect)(Marker,Marker -> OriginX,OriginY,Marker -> Width - Marker -> OriginX,1);
  311.                 }
  312.                 else
  313.                 {
  314.                     if(Delta)
  315.                         (*Marker -> Unselect)(Marker,Marker -> LastX,OriginY,Marker -> Width - Marker -> LastX,1);
  316.                     else
  317.                         (*Marker -> Unselect)(Marker,Marker -> OriginX,OriginY,Marker -> LastX - Marker -> OriginX,1);
  318.                 }
  319.  
  320.                 Marker -> LastColumn    = Marker -> OriginX;
  321.                 Marker -> LastLine    = Marker -> OriginY;
  322.  
  323.                 Marker -> LastX        = Marker -> OriginX;
  324.                 Marker -> LastY        = OriginY;
  325.             }
  326.             else
  327.             {
  328.                 if(OldCharPos > CharOrigin)
  329.                 {
  330.                     if((Lines = Marker -> LastY - Y - 1) >= 0)
  331.                     {
  332.                         if(Marker -> LastX)
  333.                             (*Marker -> Unselect)(Marker,0,Marker -> LastY,Marker -> LastX,1);
  334.  
  335.                         if(Lines > 0)
  336.                             (*Marker -> Unselect)(Marker,0,Y + 1,Marker -> Width,Lines);
  337.  
  338.                         (*Marker -> Unselect)(Marker,X,Y,Marker -> Width - X,1);
  339.                     }
  340.                     else
  341.                     {
  342.                         if(Delta)
  343.                             (*Marker -> Unselect)(Marker,X,Y,Marker -> Width - X,1);
  344.                         else
  345.                             (*Marker -> Unselect)(Marker,X,Y,Marker -> LastX - X,1);
  346.                     }
  347.  
  348.                     Marker -> LastColumn    = X;
  349.                     Marker -> LastLine    = Y + Marker -> Top;
  350.                 }
  351.             }
  352.  
  353.             if(NewCharPos < CharStart)
  354.             {
  355.                 if((Lines = Marker -> LastY - Y - 1) >= 0)
  356.                 {
  357.                     if(Marker -> LastX)
  358.                         (*Marker -> Select)(Marker,0,Marker -> LastY,Marker -> LastX,1);
  359.  
  360.                     if(Lines > 0)
  361.                         (*Marker -> Select)(Marker,0,Y + 1,Marker -> Width,Lines);
  362.  
  363.                     (*Marker -> Select)(Marker,X,Y,Marker -> Width - X,1);
  364.                 }
  365.                 else
  366.                 {
  367.                     if(Delta)
  368.                         (*Marker -> Select)(Marker,X,Y,Marker -> Width - X,1);
  369.                     else
  370.                         (*Marker -> Select)(Marker,X,Y,Marker -> LastX - X,1);
  371.                 }
  372.  
  373.                 Marker -> FirstColumn    = X;
  374.                 Marker -> FirstLine    = Y + Marker -> Top;
  375.             }
  376.         }
  377.  
  378.         Marker -> LastX = X;
  379.         Marker -> LastY = Y;
  380.     }
  381. }
  382.  
  383.  
  384.     /* ToggleSelect(struct BlockMarker *Marker,LONG Left,LONG Top,LONG Width,LONG Height):
  385.      *
  386.      *    Toggle selection subroutine.
  387.      */
  388.  
  389. VOID
  390. ToggleSelect(struct BlockMarker *Marker,LONG Left,LONG Top,LONG Width,LONG Height)
  391. {
  392.     struct RastPort *RPort = (struct RastPort *)Marker -> Object;
  393.  
  394.     if(Width && Height)
  395.     {
  396.         UWORD    OldAPen    = ReadAPen(RPort),
  397.             OldBPen    = ReadBPen(RPort),
  398.             OldDrMd    = ReadDrMd(RPort),
  399.             Mask;
  400.  
  401.         Left    = Marker -> LeftEdge + Left * Marker -> TextFontWidth;
  402.         Top    = Marker -> TopEdge + Top * Marker -> TextFontHeight;
  403.  
  404.         Mask = (1L << RPort -> BitMap -> Depth) - 1;
  405.  
  406.         if(Kick30)
  407.         {
  408.             SetABPenDrMd(RPort,Mask,OldBPen,JAM1 | COMPLEMENT);
  409.  
  410.             RectFill(RPort,Left,Top,Left + Width * Marker -> TextFontWidth - 1,Top + Height * Marker -> TextFontHeight - 1);
  411.  
  412.             SetABPenDrMd(RPort,OldAPen,OldBPen,OldDrMd);
  413.         }
  414.         else
  415.         {
  416.             SetAPen(RPort,Mask);
  417.             SetDrMd(RPort,JAM1 | COMPLEMENT);
  418.  
  419.             RectFill(RPort,Left,Top,Left + Width * Marker -> TextFontWidth - 1,Top + Height * Marker -> TextFontHeight - 1);
  420.  
  421.             SetAPen(RPort,OldAPen);
  422.             SetDrMd(RPort,OldDrMd);
  423.         }
  424.     }
  425. }
  426.  
  427.     /* WriteTrimmedString(struct IFFHandle *Handle,STRPTR String,LONG Len):
  428.      *
  429.      *    Write a string to the clipboard, sans trailing spaces.
  430.      */
  431.  
  432. VOID __regargs
  433. WriteTrimmedString(struct IFFHandle *Handle,STRPTR String,LONG Len)
  434. {
  435.     while(Len > 0 && String[Len - 1] == ' ')
  436.         Len--;
  437.  
  438.     if(Len)
  439.         WriteChunkBytes(Handle,String,Len);
  440. }
  441.  
  442.     /* TrimLength(STRPTR String,LONG Len):
  443.      *
  444.      *    Determine the length of a string, sans trailing spaces.
  445.      */
  446.  
  447. LONG __regargs
  448. TrimLength(STRPTR String,LONG Len)
  449. {
  450.     while(Len > 0)
  451.     {
  452.         if(String[Len - 1] != ' ')
  453.             break;
  454.         else
  455.             Len--;
  456.     }
  457.  
  458.     return(Len);
  459. }
  460.  
  461.     /* ClipPage(struct BlockMarker *Marker,BYTE Append):
  462.      *
  463.      *    Send the entire marked page to the clipboard.
  464.      */
  465.  
  466. STATIC VOID __inline
  467. ClipPage(struct BlockMarker *Marker,BYTE Append)
  468. {
  469.     struct IFFHandle    *Handle;
  470.     APTR             Buffer;
  471.     LONG             Size;
  472.  
  473.     if(Append)
  474.         GetClipContents(Config -> ClipConfig -> ClipboardUnit,&Buffer,&Size);
  475.     else
  476.     {
  477.         Buffer    = NULL;
  478.         Size    = 0;
  479.     }
  480.  
  481.     if(Handle = AllocIFF())
  482.     {
  483.         if(Handle -> iff_Stream = (ULONG)OpenClipboard(Config -> ClipConfig -> ClipboardUnit))
  484.         {
  485.             InitIFFasClip(Handle);
  486.  
  487.             if(!OpenIFF(Handle,IFFF_WRITE))
  488.             {
  489.                 if(!PushChunk(Handle,ID_FTXT,ID_FORM,IFFSIZE_UNKNOWN))
  490.                 {
  491.                     if(!PushChunk(Handle,0,ID_CHRS,IFFSIZE_UNKNOWN))
  492.                     {
  493.                         LONG    Lines = Marker -> LastLine - Marker -> FirstLine - 1,
  494.                             i;
  495.  
  496.                         if(Buffer)
  497.                         {
  498.                             WriteChunkBytes(Handle,Buffer,Size);
  499.  
  500.                             FreeVecPooled(Buffer);
  501.                         }
  502.  
  503.                         WriteTrimmedString(Handle,&Raster[RasterWidth * Marker -> FirstLine + Marker -> FirstColumn],Marker -> Width - Marker -> FirstColumn);
  504.                         WriteChunkBytes(Handle,"\n",1);
  505.  
  506.                         if(Lines > 0)
  507.                         {
  508.                             STRPTR Line = &Raster[(Marker -> FirstLine + 1) * RasterWidth];
  509.  
  510.                             for(i = 0 ; i < Lines ; i++)
  511.                             {
  512.                                 WriteTrimmedString(Handle,Line,Marker -> Width);
  513.                                 WriteChunkBytes(Handle,"\n",1);
  514.  
  515.                                 Line += RasterWidth;
  516.                             }
  517.                         }
  518.  
  519.                         WriteTrimmedString(Handle,&Raster[RasterWidth * Marker -> LastLine],Marker -> LastColumn);
  520.                         WriteChunkBytes(Handle,"\n",1);
  521.  
  522.                         PopChunk(Handle);
  523.                     }
  524.  
  525.                     PopChunk(Handle);
  526.                 }
  527.  
  528.                 CloseIFF(Handle);
  529.             }
  530.  
  531.             CloseClipboard((struct ClipboardHandle *)Handle -> iff_Stream);
  532.         }
  533.  
  534.         FreeIFF(Handle);
  535.     }
  536. }
  537.  
  538.     /* MarkWord(LONG MouseX,LONG MouseY):
  539.      *
  540.      *    Mark a single word on the main screen (double-click).
  541.      */
  542.  
  543. VOID __regargs
  544. MarkWord(LONG MouseX,LONG MouseY)
  545. {
  546.     LONG FirstX,FirstY;
  547.  
  548.     FirstX = MouseX / TextFontWidth;
  549.     FirstY = MouseY / TextFontHeight;
  550.  
  551.     if(FirstX > LastColumn)
  552.         FirstX = LastColumn;
  553.  
  554.     if(FirstY > LastLine)
  555.         FirstY = LastLine;
  556.  
  557.     ObtainSemaphore(RasterSemaphore);
  558.  
  559.     if(Raster[FirstY * RasterWidth + FirstX] != ' ' && Raster[FirstY * RasterWidth + FirstX])
  560.     {
  561.         STRPTR    Line = &Raster[FirstY * RasterWidth];
  562.         LONG    LastX;
  563.  
  564.         LastX = FirstX;
  565.  
  566.         while(FirstX > 0 && Line[FirstX - 1] != ' ')
  567.             FirstX--;
  568.  
  569.         while(LastX < LastColumn && Line[LastX + 1] != ' ')
  570.             LastX++;
  571.  
  572.         ObtainSemaphore(&TerminalSemaphore);
  573.  
  574.         if(WindowMarker = BM_SetMark(Window -> RPort,ToggleSelect,ToggleSelect,LastColumn + 1,LastLine + 1,WindowLeft,WindowTop,0,LastLine + 1,FirstX,FirstY,TextFontWidth,TextFontHeight))
  575.         {
  576.             SetWrMsk(RPort,DepthMask);
  577.  
  578.             Marking = TRUE;
  579.  
  580.             ReportMouse(TRUE,Window);
  581.  
  582.             BM_ExtendMark(WindowMarker,LastX + 1,FirstY,0);
  583.  
  584.             SetClipMenu(TRUE);
  585.         }
  586.  
  587.         ReleaseSemaphore(&TerminalSemaphore);
  588.     }
  589.  
  590.     ReleaseSemaphore(RasterSemaphore);
  591. }
  592.  
  593.     /* SetMarker(LONG MouseX,LONG MouseY):
  594.      *
  595.      *    Anchor a marker to the current mouse position.
  596.      */
  597.  
  598. VOID __regargs
  599. SetMarker(LONG MouseX,LONG MouseY)
  600. {
  601.     LONG FirstX,FirstY;
  602.  
  603.     FirstX = MouseX / TextFontWidth;
  604.     FirstY = MouseY / TextFontHeight;
  605.  
  606.     if(FirstX > LastColumn)
  607.         FirstX = LastColumn;
  608.  
  609.     if(FirstY > LastLine)
  610.         FirstY = LastLine;
  611.  
  612.     ObtainSemaphore(&TerminalSemaphore);
  613.  
  614.     if(WindowMarker = BM_SetMark(Window -> RPort,ToggleSelect,ToggleSelect,LastColumn + 1,LastLine + 1,WindowLeft,WindowTop,0,LastLine + 1,FirstX,FirstY,TextFontWidth,TextFontHeight))
  615.     {
  616.         SetWrMsk(RPort,DepthMask);
  617.  
  618.         Marking = TRUE;
  619.  
  620.         ReportMouse(TRUE,Window);
  621.  
  622.         SetClipMenu(TRUE);
  623.     }
  624.  
  625.     ReleaseSemaphore(&TerminalSemaphore);
  626. }
  627.  
  628.     /* MoveMarker(LONG MouseX,LONG MouseY):
  629.      *
  630.      *    Move the marker with the mouse.
  631.      */
  632.  
  633. VOID __regargs
  634. MoveMarker(LONG MouseX,LONG MouseY)
  635. {
  636.     if(WindowMarker)
  637.     {
  638.         ObtainSemaphore(&TerminalSemaphore);
  639.  
  640.         BM_ExtendMark(WindowMarker,(MouseX + TextFontWidth - 1) / TextFontWidth,MouseY / TextFontHeight,0);
  641.  
  642.         ReleaseSemaphore(&TerminalSemaphore);
  643.     }
  644. }
  645.  
  646.     /* DropMarker():
  647.      *
  648.      *    Drop the window marker, restore the window contents.
  649.      */
  650.  
  651. VOID
  652. DropMarker()
  653. {
  654.     if(WindowMarker)
  655.     {
  656.         struct RastPort    *RPort    = WindowMarker -> Object;
  657.         UBYTE         Mask    = WindowMarker -> WriteMask;
  658.  
  659.         ObtainSemaphore(&TerminalSemaphore);
  660.  
  661.         BM_ClearMark(WindowMarker);
  662.  
  663.         ReleaseSemaphore(&TerminalSemaphore);
  664.  
  665.         SetWrMsk(RPort,Mask);
  666.  
  667.         ReportMouse(FALSE,Window);
  668.  
  669.         WindowMarker = NULL;
  670.  
  671.         Marking = FALSE;
  672.  
  673.         SetClipMenu(FALSE);
  674.     }
  675. }
  676.  
  677.     /* FreeMarker():
  678.      *
  679.      *    Free the main window marker.
  680.      */
  681.  
  682. VOID
  683. FreeMarker()
  684. {
  685.     if(WindowMarker)
  686.     {
  687.         struct RastPort    *RPort    = WindowMarker -> Object;
  688.         UBYTE         Mask    = WindowMarker -> WriteMask;
  689.  
  690.         FreeVecPooled(WindowMarker);
  691.  
  692.         WindowMarker = NULL;
  693.  
  694.         SetWrMsk(RPort,Mask);
  695.  
  696.         ReportMouse(FALSE,Window);
  697.  
  698.         Marking = FALSE;
  699.  
  700.         SetClipMenu(FALSE);
  701.     }
  702. }
  703.  
  704.     /* ClipMarker(BYTE Append):
  705.      *
  706.      *    Transfer the marked area to the clipboard.
  707.      */
  708.  
  709. VOID __regargs
  710. ClipMarker(BYTE Append)
  711. {
  712.     if(WindowMarker)
  713.     {
  714.         ObtainSemaphore(RasterSemaphore);
  715.  
  716.         SetWait(Window);
  717.  
  718.         if(WindowMarker -> FirstColumn == WindowMarker -> Width)
  719.         {
  720.             WindowMarker -> FirstLine++;
  721.  
  722.             WindowMarker -> FirstColumn = 0;
  723.         }
  724.  
  725.         if(WindowMarker -> LastColumn == 0)
  726.         {
  727.             WindowMarker -> LastLine--;
  728.  
  729.             WindowMarker -> LastColumn = WindowMarker -> Width;
  730.         }
  731.  
  732.         if(WindowMarker -> FirstLine <= WindowMarker -> LastLine)
  733.         {
  734.             if(WindowMarker -> FirstLine != WindowMarker -> LastLine || WindowMarker -> FirstColumn != WindowMarker -> LastColumn)
  735.             {
  736.                 if(WindowMarker -> FirstLine == WindowMarker -> LastLine)
  737.                 {
  738.                     if(Append)
  739.                         AddClip(&Raster[RasterWidth * WindowMarker -> FirstLine + WindowMarker -> FirstColumn],WindowMarker -> LastColumn - WindowMarker -> FirstColumn);
  740.                     else
  741.                         SaveClip(&Raster[RasterWidth * WindowMarker -> FirstLine + WindowMarker -> FirstColumn],WindowMarker -> LastColumn - WindowMarker -> FirstColumn);
  742.                 }
  743.                 else
  744.                     ClipPage(WindowMarker,Append);
  745.             }
  746.         }
  747.  
  748.         ClrWait(Window);
  749.  
  750.         ReleaseSemaphore(RasterSemaphore);
  751.  
  752.         DropMarker();
  753.     }
  754. }
  755.