home *** CD-ROM | disk | FTP | other *** search
/ The Developer Connection…ice Driver Kit for OS/2 3 / DEV3-D1.ISO / editors / epm / sampmacs / clipbrd.e < prev    next >
Encoding:
Text File  |  1993-12-02  |  33.5 KB  |  756 lines

  1. /*
  2. ╔════════════════════════════════════════════════════════════════════════════╗
  3. ║ What's it called: clipbrd.e                                                ║
  4. ║                                                                            ║
  5. ║ What does it do:  contains procedures and commands that all:               ║
  6. ║                  -Allow one to pass lines of text between edit windows     ║
  7. ║                  -Allow text to be placed in the PM clipboard              ║
  8. ║                                                                            ║
  9. ║                Text Manipulation between Edit Windows                      ║
  10. ║                ======================================                      ║
  11. ║                Copy2SharBuff  -  Copy Marked area to EPM shared buffer     ║
  12. ║                GetSharBuff    -  Get text from EPM shared buffer           ║
  13. ║                ClearSharBuf   -  Flush out Stuff in shared buffer          ║
  14. ║                Copy2DMBuff    -  Copy Marked area to "Delete Mark" buffer  ║
  15. ║                GetDMBuff    -  Get text from "Delete Mark" buffer          ║
  16. ║                                                                            ║
  17. ║                Text Manipulation between an Edit Window and PM clipboard   ║
  18. ║                ========================================================    ║
  19. ║                                                                            ║
  20. ║                copy2clip - copy marked text to the PM clipboard.           ║
  21. ║                                                                            ║
  22. ║                cut - like copy2clip, but deletes the marked text.          ║
  23. ║                                                                            ║
  24. ║                paste - retrieve text from PM clipboard to edit window.     ║
  25. ║                                                                            ║
  26. ║                                                                            ║
  27. ║ Who and When: Ralph Yozzo, Gennaro (Jerry) Cuomo, & Larry Margolis 3-88    ║
  28. ║                                                                    6/89    ║
  29. ╚════════════════════════════════════════════════════════════════════════════╝
  30. */
  31. compile if EVERSION >= 5.60
  32.    #define CR_TERMINATOR_LDFLAG           1  -- Use CR as a terminator
  33.    #define LF_TERMINATOR_LDFLAG           2  -- Use LF as a terminator
  34.    #define CRLF_TERMINATOR_LDFLAG         4  -- Use CR,LF as a terminator
  35.    #define CTRLZ_TERMINATOR_LDFLAG        8  -- Use EOF as a terminator
  36.    #define NULL_TERMINATOR_LDFLAG        16  -- Use NULL as a terminator
  37.    #define TABEXP_LDFLAG                 32  -- Expand tabs when loading
  38.    #define CRLFEOF_TERMINATOR_LDFLAG     64  -- Use CR,LF,EOF as a terminator
  39.    #define CRCRLF_TERMINATOR_LDFLAG     128  -- Use CR,CR,LF as a terminator
  40.    #define NOHEADER_LDFLAG              256  -- Buffer has no header
  41.    #define NEW_BITS_LDFLAG              512  -- Format flag is using these bits
  42.    #define STRIP_SPACES_LDFLAG         1024  -- Strip trailing spaces when loading
  43.    #define IGNORE_STORED_FORMAT_LDFLAG 2048  -- Don't use format flags saved in buffer header
  44.    #define FORCE_TERMINATOR_LDFLAG     4096  -- Require a terminator after every line
  45. compile endif
  46. /*
  47. ┌────────────────────────────────────────────────────────────────────────────┐
  48. │ Copy2SharBuff -                                                            │
  49. │                 Copy Marked area to EPM shared buffer                      │
  50. │                                                                            │
  51. │                                                                            │
  52. └────────────────────────────────────────────────────────────────────────────┘
  53. */
  54. defc Copy2SharBuff                     /* former name = CLIPBRD_pt          */
  55.    if not marktype() then              /* check if mark exists              */
  56.       return                           /* if mark doesn't exist, return     */
  57.    endif
  58.                                        /* save the dimensions of the mark   */
  59. compile if EVERSION >= 5.50
  60.    getmarkg fstline,                   /* returned:  first line of mark     */
  61. compile else
  62.    getmark fstline,                    /* returned:  first line of mark     */
  63. compile endif
  64.            lstline,                    /* returned:  last  line of mark     */
  65.            fstcol,                     /* returned:  first column of mark   */
  66.            lstcol,                     /* returned:  last  column of mark   */
  67.            mkfileid                    /* returned:  file id of marked file */
  68.  
  69.    getfileid fileid                    /* save file id of visible file      */
  70.    activatefile mkfileid               /* switch to file with mark          */
  71.    /* Try to open the buffer.  If it doesn't exist, create it.              */
  72.    bufhndl = buffer(OPENBUF, EPMSHAREDBUFFER)
  73.    if bufhndl then
  74.       opened = 1
  75.    else
  76.       -- Make a 64K buffer... memory's plentiful.  Easily changed.
  77.       bufsize = MAXBUFSIZE
  78.       bufhndl = buffer(CREATEBUF, EPMSHAREDBUFFER, bufsize)
  79.       opened = 0
  80.    endif
  81.    if not bufhndl then
  82.       sayerror CAN_NOT_OPEN__MSG EPMSHAREDBUFFER '-' ERROR_NUMBER__MSG RC
  83.       stop
  84.    endif
  85.  
  86.    /* Copy the current marked lines (up to 64k worth of data ) into EPM's */
  87.    /* shared memory buffer.                                               */
  88. compile if EVERSION >= 5.51
  89.    call buffer(PUTMARKBUF, bufhndl, fstline, lstline, APPENDCR+APPENDLF+STRIPSPACES)  -- Was +FINALNULL
  90. compile else  -- Older versions needed the null for the copy to clipboard routine
  91.    call buffer(PUTMARKBUF, bufhndl, fstline, lstline, APPENDCR+APPENDLF+STRIPSPACES+FINALNULL)
  92. compile endif
  93.  
  94. compile if EVERSION >= 5.50
  95.    poke bufhndl, 28, atol(lstline-fstline+1-(lstline>.last))  -- Remember how many lines are *supposed* to be there.
  96. compile else
  97.    poke bufhndl, 28, atol(lstline-fstline+1)  -- Remember how many lines are *supposed* to be there.
  98. compile endif
  99.  
  100.    activatefile fileid
  101.    if opened then
  102.       call buffer(FREEBUF, bufhndl)
  103.    endif
  104.  
  105. /*
  106. ┌────────────────────────────────────────────────────────────────────────────┐
  107. │ GetSharBuff -                                                              │
  108. │                 Get text from EPM shared buffer.                           │
  109. │                 'O' means Overlay instead of copy.                         │
  110. │                                                                            │
  111. └────────────────────────────────────────────────────────────────────────────┘
  112. */
  113. defc GetSharBuff            /* former name = CLIPBRD_gt                 */
  114.    /* EPMSHAREDBUFFER= buffer name known between edit windows           */
  115.    -- Try to open the buffer.  If it doesn't exist, nothing to get.
  116.    bufhndl = buffer(OPENBUF, EPMSHAREDBUFFER)
  117.    if not bufhndl then
  118.       sayerror CAN_NOT_OPEN__MSG EPMSHAREDBUFFER '-' ERROR_NUMBER__MSG RC
  119.       stop
  120.    endif
  121.    call psave_pos(save_pos)
  122.    call GetBuffCommon(bufhndl, NO_MARK_NO_BUFF__MSG, arg(1))
  123.    call buffer(FREEBUF, bufhndl)
  124.    call prestore_pos(save_pos)
  125.  
  126. /*
  127. ┌────────────────────────────────────────────────────────────────────────────┐
  128. │ ClearSharBuff -                                                            │
  129. │                 Flush out stuff in  EPM shared buffer                      │
  130. │                                                                            │
  131. └────────────────────────────────────────────────────────────────────────────┘
  132. */
  133. defc ClearSharBuff
  134.    bufhndl=buffer(OPENBUF, EPMSHAREDBUFFER)
  135.    if bufhndl then
  136.       call buffer(CLEARBUF, bufhndl)
  137.       call buffer(FREEBUF, bufhndl)
  138.    endif
  139.  
  140. /*
  141. ┌────────────────────────────────────────────────────────────────────────────┐
  142. │ copy2clip                                                                  │
  143. │       copy marked text into the PM clipboard.                              │
  144. │                                                                            │
  145. │                                                                            │
  146. └────────────────────────────────────────────────────────────────────────────┘
  147. */
  148. defc copy2clip
  149.    call checkmark()                          /* Make sure there's a mark. */
  150.  
  151.    'Copy2SharBuff'   -- Recopy the marked area to the shared buffer,
  152.                      -- in case the user has modified the mark contents.
  153.  
  154.    /* Try to open the buffer.  If it doesn't exist, then we can't copy   */
  155.    bufhndl = buffer(OPENBUF, EPMSHAREDBUFFER)
  156.    if not bufhndl then
  157.       return 1                              /* buffer does not exist     */
  158.    endif
  159.    if peek(bufhndl,6,2) /== peek(bufhndl,28,2) then
  160.       sayerror TOO_MUCH_FOR_CLIPBD__MSG
  161.       return 1
  162.    endif
  163.  
  164. compile if EVERSION < '5.50'
  165.    hab=gethwnd(0)                           /* get EPM's anchorblock     */
  166.    call dynalink('PMWIN',                   /* Open PM's clipboard       */
  167.                  'WINOPENCLIPBRD',
  168.                  hab)
  169.  
  170.    call dynalink('PMWIN',                   -- Empty the clipboard completely
  171.                  'WINEMPTYCLIPBRD',         -- before filling it.
  172.                  hab)
  173.    result = dynalink(EUTIL_DLL,             /* create a buffer and copy  */
  174.             'CLIPBOARDCOPY',                /* the contents of the EPM   */
  175.             atoi(bufhndl)||                 /* shared buffer             */
  176.             atoi(0)      ||
  177.             atoi(1),                        /* buffer to pm clipboard    */
  178.             2)                              /* return long               */
  179.  
  180.    /* Clipboardcopy allocates a buffer of memory                         */
  181.    /* we don't have to worry about freeing the buffer that clipboardcopy */
  182.    /* allocates... PM will free it                                       */
  183.  
  184.    call dynalink('PMWIN',                   /* call PM function to       */
  185.                  'WINSETCLIPBRDDATA',       /* move data into the PM e cb*/
  186.                   hab ||                    /* anchor block              */
  187.                   atol(result) ||           /* pointer to text.          */
  188.                   atoi(1) ||                /* format (TEXT)             */
  189.                   atoi(256))                /* selector                  */
  190.  
  191.    call dynalink('PMWIN',
  192.                  'WINCLOSECLIPBRD',
  193.                  hab)
  194.    call buffer(FREEBUF, bufhndl)
  195.  
  196. compile else
  197. --  Copying to the Clipboard using the EToolkit message:
  198. --  EPM_EDIT_CLIPBOARDCOPY -  mp1 = pointer to memory buffer containing
  199. --                                  contents to copy to the clipboard.
  200. --                            mp2 = flag that describes what type of buffer
  201. --                                  was passed in mp1.
  202. --                                  0=CF_TEXT type buffer, terminated by nul
  203. --                                  1=EPM shared memory buffer (32byte head)
  204. --  When the contents of mp1 is copied to the clipboard a EPM defc event is
  205. --  called by the name of PROCESSCLIPBOARDCOPY.  Arg(1) of this function is
  206. --  the original buffer passed in as mp1.  The caller may choose to free
  207. --  the buffer during this command.    if zero is passed as arg(1), an error
  208. --  was encountered.  An error message should be displayed at this point.
  209.  
  210.    call windowmessage(0,  getpminfo(EPMINFO_EDITCLIENT),
  211.                       5441,               -- EPM_EDIT_CLIPBOARDCOPY
  212.                       mpfrom2short( bufhndl, 0),
  213.                       1)
  214.  
  215. defc processclipboardcopy
  216.    result=arg(1)
  217.    if not result then      -- If non-zero, free the buffer.
  218.       call buffer(FREEBUF, itoa(substr(atol(result),3,2),10))  -- pass just the selector
  219.    endif
  220.  
  221. compile endif -- EVERSION < '5.50'
  222.  
  223. /*
  224. ┌────────────────────────────────────────────────────────────────────────────┐
  225. │ cut                                                                        │
  226. │       copy marked text into the PM clipboard, then delete the mark.        │
  227. │                                                                            │
  228. │                                                                            │
  229. └────────────────────────────────────────────────────────────────────────────┘
  230. */
  231. defc cut
  232.    'copy2clip'
  233.    if not RC then
  234.       getmark firstline,lastline,firstcol,lastcol,markfileid
  235.       markfileid.line = firstline
  236.       if leftstr(marktype(), 1)<>'L' then
  237.          markfileid.col = firstcol
  238.       endif
  239.       call pdelete_mark()
  240.    endif
  241.  
  242. /*
  243. ┌─────────────────────────────────────────────────────────────────────────┐
  244. │ paste                                                                   │
  245. │                                                                         │
  246. │    retrieve text from PM clipboard to edit window                       │
  247. │                                                                         │
  248. └─────────────────────────────────────────────────────────────────────────┘
  249. */
  250. defc paste
  251. compile if WANT_CUA_MARKING = 'SWITCH'
  252.    universal CUA_marking_switch
  253. compile endif
  254.    arg1 = upcase(arg(1))
  255.    if browse() then
  256.       sayerror BROWSE_IS__MSG ON__MSG
  257.       return
  258.    endif
  259.    if not .line & (arg1='C' | arg1='B') then
  260.       sayerror -281  -- "Source destination conflict"
  261.       return
  262.    endif
  263. compile if EVERSION < '5.50'
  264.    if not clipcheck(format) then
  265.       sayerror CLIPBOARD_ERROR__MSG
  266.       return
  267.    endif
  268.    if format<>256 then                 -- no text in clipboard
  269.       sayerror CLIPBOARD_EMPTY__MSG
  270.       return
  271.    endif
  272.  
  273. compile if EPM32
  274.    hab=gethwndc(0)                          -- get EPM's anchorblock
  275.    call dynalink32('PMWIN',                   /* Open PM's clipboard       */
  276.                    '#793',  -- WINOPENCLIPBRD
  277.                     hab)
  278.  
  279.    result = dynalink32('PMWIN',               /* call PM function to       */
  280.                        '#806',  -- WINQUERYCLIPBRDDATA  /* look at the data in the cb*/
  281.                        hab ||                 /* anchor block              */
  282.                        atol(1),               /* data format ( TEXT )      */
  283.                        4)                     /* return a 4 byte result    */
  284.  
  285.    result = dynalink32(EUTIL_DLL,             /* create a buffer and copy  */
  286.                        'ClipboardCopy',       /*                           */
  287.                        atol(result) ||        /*                           */
  288.                        atol(0),               /* pm clipboard to shared buf*/
  289.                        4)                     /*                           */
  290.    call dynalink32('PMWIN',
  291.                    '#707',  -- WINCLOSECLIPBRD
  292.                    hab)
  293. compile else
  294.    hab=gethwnd(0)                          -- get EPM's anchorblock
  295.    call dynalink('PMWIN',                   /* Open PM's clipboard       */
  296.                  'WINOPENCLIPBRD',
  297.                  hab)
  298.  
  299.    result = dynalink('PMWIN',               /* call PM function to       */
  300.                      'WINQUERYCLIPBRDDATA', /* look at the data in the cb*/
  301.                      hab ||                 /* anchor block              */
  302.                      atoi(1),               /* data format ( TEXT )      */
  303.                      2)                     /* return a 4 byte result    */
  304.  
  305.    result = dynalink(EUTIL_DLL,             /* create a buffer and copy  */
  306.                      'CLIPBOARDCOPY',       /*                           */
  307.                      atol(result) ||        /*                           */
  308.                      atoi(0),               /* pm clipboard to shared buf*/
  309.                      2)                     /*                           */
  310.    call dynalink('PMWIN',
  311.                  'WINCLOSECLIPBRD',
  312.                  hab)
  313. compile endif  -- EPM32
  314.  
  315.    result=itoa(substr(atol(result),3,2),10) /* convert from bin to str   */
  316.    if arg1='C' | arg1='B' then
  317.       poke result, 8, chr(68-asc(arg1))              -- 'C'->1; 'B'->2; mark as a character or block buffer
  318.  compile if WANT_CUA_MARKING
  319.       if arg1='C' &
  320.   compile if WANT_CUA_MARKING = 'SWITCH'
  321.          CUA_marking_switch &
  322.   compile endif
  323.          marktype()
  324.       then
  325.          call pbegin_mark()
  326.          call pdelete_mark()
  327.          'ClearSharBuff'       /* Remove Content in EPM shared text buffer */
  328.       endif
  329.  compile endif
  330.       call psave_mark(savemark)                        -- Save the user's mark
  331.       call GetBuffCommon(result, NOTHING_TO_PASTE__MSG, arg1)
  332.       -- clause continued below for common stuff.
  333. compile else  -- if EVERSION < 5.50
  334. --  Pasting from the PM Clipboard using the EToolkit message:
  335. --  EPM_EDIT_CLIPBOARDPASTE-  mp1 = flag that describes the type of paste
  336. --                                  that is desired.  A paste could be of
  337. --                            the following types; 'C' for Character, 'B' for
  338. --                            block and 'L' for line.
  339. --  During the processing of this message the text in the PM clipboard is
  340. --  queried.  Once this is done an EPM defc event is
  341. --  called by the name of PROCESSCLIPBOARDPASTE.  Arg(1) of this function
  342. --  contains a pointer to a buffer containing a copy of the text found in
  343. --  the PM clipboard.   Arg(2) of this function is
  344. --  the original flag passed in as mp1.  The caller may choose to free
  345. --  the buffer during this command.    if zero is passed as arg(1), an error
  346. --  was encountered.  An error message should be displayed at this point.
  347.    mark=upcase(arg(1))
  348.    if mark<>'C' and  mark<>'B' then
  349.       mark='L'
  350.    endif
  351.    call windowmessage(0,  getpminfo(EPMINFO_EDITCLIENT),
  352.                       5442,               -- EPM_EDIT_CLIPBOARDPASTE
  353.                       asc(mark), 0)
  354.  
  355. defc processclipboardpaste
  356.  compile if WANT_CUA_MARKING = 'SWITCH'
  357.    universal CUA_marking_switch
  358.  compile endif
  359.  
  360.    parse arg result mark .
  361.    if not result then
  362.       sayerror CLIPBOARD_ERROR__MSG
  363.       return
  364.    endif
  365.  
  366.    if mark=67 | mark=66 then  -- asc('C') | asc('B')
  367.       poke result, 8, chr(68-mark)              -- 'C'->1; 'B'->2; mark as a character or block buffer
  368.  compile if WANT_CUA_MARKING
  369.       if mark=67 &
  370.   compile if WANT_CUA_MARKING = 'SWITCH'
  371.          CUA_marking_switch &
  372.   compile endif
  373.          marktype()
  374.       then
  375.          getmark x, x, x, x, mark_fid
  376.          getfileid cur_fid
  377.          if mark_fid=cur_fid then
  378.             call pbegin_mark()
  379.             call pdelete_mark()
  380.          else
  381.             unmark
  382.             sayerror MARKED_OTHER__MSG
  383.          endif
  384.          'ClearSharBuff'       /* Remove content in EPM shared text buffer */
  385.       endif
  386.  compile endif
  387.       call psave_mark(savemark)                        -- Save the user's mark
  388.       call GetBuffCommon(result, NOTHING_TO_PASTE__MSG, chr(mark))
  389. compile endif -- EVERSION < '5.50'
  390.       -- Two cases join here, in the middle of this IF statement.
  391.       call prestore_mark(savemark)                     -- Restore the user's mark
  392.    else
  393.       oldsize = .last
  394. compile if EVERSION >= 5.60
  395.       call buffer(GETBUF2, result, 1, 0,
  396.                   CR_TERMINATOR_LDFLAG + LF_TERMINATOR_LDFLAG + CRLF_TERMINATOR_LDFLAG +
  397.                   CRCRLF_TERMINATOR_LDFLAG + NEW_BITS_LDFLAG + FORCE_TERMINATOR_LDFLAG)
  398.       if textline(.line+.last-oldsize)=='' then
  399.          deleteline .line+.last-oldsize
  400.       endif
  401. compile elseif EVERSION >= 5.50
  402.       call buffer(GETBUF2, result)          /* put buffer into text      */
  403. compile else
  404.       call buffer(GETBUF, result)           /* put buffer into text      */
  405. compile endif -- EVERSION >= 5.50
  406.       '+'(.last-oldsize)
  407.    endif
  408.  
  409. compile if EPM32
  410.    call dynalink32('DOSCALLS',        /* dynamic link library name         */
  411.                    '#304',             /* DosFreeSeg                        */
  412.                    ltoa(atoi(0) || atoi(result), 10))
  413. compile else
  414.    call dynalink('DOSCALLS',        /* dynamic link library name         */
  415.                  '#39',             /* DosFreeSeg                        */
  416.                  atoi(result))
  417. compile endif
  418.  
  419. compile if WANT_DM_BUFFER
  420. definit
  421.    universal DMbuf_handle
  422.    DMbuf_handle = 0
  423.  
  424. defexit
  425.    universal DMbuf_handle
  426.    if DMbuf_handle then
  427.       call buffer(FREEBUF, DMbuf_handle)              -- Free the OPEN
  428.    endif
  429.  
  430. /*
  431. ┌────────────────────────────────────────────────────────────────────────────┐
  432. │ Copy2DMBuff -                                                              │
  433. │                 Copy Marked area to "Delete Mark" buffer                   │
  434. │                                                                            │
  435. │                                                                            │
  436. └────────────────────────────────────────────────────────────────────────────┘
  437. */
  438. defc Copy2DMBuff
  439.    universal DMbuf_handle
  440.    themarktype = marktype()
  441.    if not themarktype then             /* check if mark exists              */
  442.       return                           /* if mark doesn't exist, return     */
  443.    endif
  444.                                        /* save the dimensions of the mark   */
  445.    getmark fstline,                    /* returned:  first line of mark     */
  446.            lstline,                    /* returned:  last  line of mark     */
  447.            fstcol,                     /* returned:  first column of mark   */
  448.            lstcol,                     /* returned:  last  column of mark   */
  449.            mkfileid                    /* returned:  file id of marked file */
  450.  
  451.    if themarktype='BLOCK' then  -- Size of block, + 2 per line for CR, LF
  452.       size=(lstcol-fstcol+3) * (lstline-fstline+1) + 3
  453.    else                       -- Probably much larger than we need, but must assume:
  454.       size=(MAXCOL+2) * (lstline-fstline+1) +3  -- 255 chars/line + CR, LF
  455.    endif
  456.    /* Try to open the buffer.  If it doesn't exist or is too small, create it. */
  457.    if not DMbuf_handle then
  458.       DMbuf_handle = buffer(OPENBUF, EPMDMBUFFER)
  459.       if DMbuf_handle then
  460.          call buffer(FREEBUF, DMbuf_handle)              -- Free the OPEN
  461.       endif
  462.    endif
  463.    if DMbuf_handle then
  464.       maxsize  = buffer(MAXSIZEBUF,DMbuf_handle)
  465.       if size > maxsize & maxsize < MAXBUFSIZE then
  466.          success=buffer(FREEBUF, DMbuf_handle)        -- Free the original CREATE
  467.          if not success then
  468.             sayerror ERROR__MSG rc TRYING_TO_FREE__MSG EPMDMBUFFER BUFFER__MSG
  469.          endif
  470.          DMbuf_handle = ''
  471.       endif
  472.    endif
  473.    if not DMbuf_handle then
  474.       DMbuf_handle = buffer(CREATEBUF, EPMDMBUFFER, min(size,MAXBUFSIZE), 1)
  475.    endif
  476.    if not DMbuf_handle then
  477.       messageNwait(CAN_NOT_OPEN__MSG EPMDMBUFFER '-' ERROR_NUMBER__MSG RC)
  478.       return
  479.    endif
  480.  
  481.    getfileid fileid                    /* save file id of visible file      */
  482.    activatefile mkfileid               /* switch to file with mark          */
  483.    /* Copy the current marked lines (up to 64k worth of data ) into EPM's */
  484.    /* shared memory buffer.                                               */
  485.    call buffer(PUTMARKBUF, DMbuf_handle, fstline, lstline, APPENDCR+APPENDLF+STRIPSPACES)
  486.  
  487.    poke DMbuf_handle, 28, atol(lstline-fstline+1)  -- Remember how many lines are *supposed* to be there.
  488.  
  489.    activatefile fileid
  490.  
  491.  
  492. /*
  493. ┌────────────────────────────────────────────────────────────────────────────┐
  494. │ GetDMBuff -                                                                │
  495. │                 Get text from "Delete Mark" buffer.                        │
  496. │                                                                            │
  497. │                                                                            │
  498. └────────────────────────────────────────────────────────────────────────────┘
  499. */
  500. defc GetDMBuff
  501.    universal DMbuf_handle
  502.    -- Try to open the buffer.  If it doesn't exist, nothing to get.
  503. ;; DMbuf_handle = buffer(OPENBUF, EPMDMBUFFER)
  504. ;; -- (If it doesn't exist in this window, the lines were deleted from some other window.)
  505.    if not DMbuf_handle then
  506. ;;    sayerror 'Unable to open a buffer named' EPMDMBUFFER'.  Error number 'RC
  507.       sayerror NO_MARK_DELETED__MSG
  508.       return
  509.    endif
  510.    call psave_mark(savemark)                              -- Save the user's mark
  511.    call GetBuffCommon(DMbuf_handle, NO_TEXT_RECOVERED__MSG)  -- (This marks what's recovered)
  512.    call prestore_mark(savemark)                           -- Restore the user's mark
  513. compile endif  -- WANT_DM_BUFFER
  514.  
  515.  
  516. /*
  517. ┌────────────────────────────────────────────────────────────────────────────┐
  518. │ GetBuffCommon                                                              │
  519. │                 Common code called by GetSharBuff, Paste and GetDMBuff     │
  520. │                                                                            │
  521. └────────────────────────────────────────────────────────────────────────────┘
  522. */
  523. defproc GetBuffCommon(bufhndl, errormsg)
  524.    markt = buffer(MARKTYPEBUF, bufhndl)
  525.    getfileid activefid                  -- get current files file id
  526.    if not markt & arg(3)<>'O' then      -- MARKT=0 ==> line mark (simple case)
  527.       noflines = buffer(GETBUF, bufhndl)   -- Retrieve data from shared EPM buf
  528.       if noflines then
  529.          call pset_mark(.line+1,.line+noflines,1,MAXCOL,'LINE',activefid)
  530.          '+'noflines
  531.          call verify_buffer_size(bufhndl, noflines)
  532.       else
  533.          sayerror errormsg
  534.       endif
  535.       return                            -- ... and that's all.
  536.    endif
  537.  
  538.    cur_line_len = length(textline(.line))
  539.    'xcom e /q /c epmbuff.cpy'           -- edit a temp hidden file
  540.    .visible=0                           -- (hide file)
  541.    getfileid tmpfileid                  -- get hidden file's id
  542.  
  543. compile if EVERSION >= 5.60
  544.    noflines = buffer(GETBUF2, bufhndl, 1, 0,
  545.                      CR_TERMINATOR_LDFLAG + LF_TERMINATOR_LDFLAG + CRLF_TERMINATOR_LDFLAG +
  546.                      CRCRLF_TERMINATOR_LDFLAG + NEW_BITS_LDFLAG + FORCE_TERMINATOR_LDFLAG)
  547. compile elseif EVERSION >= 5.50
  548.    noflines = buffer(GETBUF2, bufhndl)  -- retrieve data from shared EPM buf
  549. compile else
  550.    noflines = buffer(GETBUF, bufhndl)   -- retrieve data from shared EPM buf
  551. compile endif -- EVERSION >= 5.50
  552.    if not noflines then
  553.       'xcom quit'
  554.       sayerror errormsg
  555.       return
  556.    endif
  557. compile if EVERSION < 5.50
  558.    insert_attribute 13, 0, 2, 0, activefid.col, activefid.line, activefid  -- Place a bookmark on the character
  559. compile endif
  560.  
  561. compile if EVERSION >= 5.50
  562.    orig_lines = ltoa(peek(bufhndl,28,4),10)
  563.  compile if EVERSION = 5.50
  564.    if orig_lines & orig_lines = noflines-1 & markt = 2 & textline(.last)==\0 then  -- Block mark?  Get rid of extra blank line
  565.  compile else
  566.    if orig_lines & orig_lines = noflines-1 & markt = 2 & textline(.last)=='' then  -- Block mark?  Get rid of extra blank line
  567.  compile endif
  568.       noflines = noflines-1
  569.       deleteline .last
  570.    endif
  571. compile endif
  572.    length_last = length(textline(.last))
  573.    split_start = 0; split_end = 0
  574.    '+1'                              -- advance to next line in hidden
  575.    if markt=2 | markt=4 then            -- Mark type is BLOCK(G)
  576.       markblock                         -- block mark first character
  577.       noflines+1                        -- advance down to last line
  578.       if arg(3)='B' then                -- Block-marking from clipboard;
  579.          .col=longestline()             -- move cursor to end of longest line
  580.       else                              -- Was originally a block; width is OK.
  581.          .col=length_last               -- move to last character
  582.       endif
  583.       markblock                         -- complete block mark
  584.    elseif markt=1 | markt=3 then        -- Mark type is Character(G)
  585.       split_start = activefid.col + length(textline(2)) > MAXCOL
  586.       split_end = cur_line_len - activefid.col + length_last > MAXCOL
  587. compile if EVERSION >= 5.50
  588.       setmark 2, .last, 1, length_last+1, 3, tmpfileid  -- 3 = CHARG mark
  589. compile else
  590.       mark_char                         -- character mark first char
  591.       noflines+1                        -- advance down to last
  592.       .col=length_last                  -- move to last character
  593.       mark_char                         -- complete character mark
  594. compile endif
  595.    else
  596.       mark_line                         -- line mark first line
  597.       noflines+1                        -- advance down to last
  598.       mark_line                         -- complete line mark
  599.    endif
  600.  
  601.    activatefile activefid               -- activate destination file
  602.    rc=0                                 -- clear return code before copy
  603.    if arg(3)='O' then
  604. compile if WANT_CHAR_OPS
  605.       call pcommon_adjust_overlay('O')  -- copy mark
  606. compile else
  607.       overlay_block
  608. compile endif
  609.    else
  610.       if split_end then split; endif
  611.       if split_start then split; '+1'; begin_line; endif
  612.       call pcopy_mark()                 -- copy mark
  613.    endif
  614.    if rc then                           -- Test for memory too full for copy_mark.
  615.       display -4
  616.       sayerror ERROR_COPYING__MSG
  617.       display 4
  618.    endif
  619.  
  620.    activatefile tmpfileid               -- activate temp file
  621.    'xcom q'                             -- quit it
  622.    activatefile activefid               -- activate destination file
  623. compile if EVERSION < 5.50
  624.    class = 13  -- BOOKMARK_CLASS
  625.    col=.col+1; line=.line; offst=0
  626.    attribute_action 1, class, offst, col, line  -- 1=FIND NEXT ATTR
  627.    if class=13 then
  628.       query_attribute class, val, IsPush, offst, col, line
  629.       line; .col=col
  630.       attribute_action 16, class, offst, col, line -- 16=Delete attribute
  631.    endif
  632. compile else  -- 5.50 does char marks internally, so moving to the end of the mark will always work.
  633.    call pend_mark()
  634. ;  sayerror 'length_last='length_last'; .col='.col'; cl1, cl2 =' cl1 cl2
  635.    if length_last then executekey right; endif
  636. compile endif
  637.    call verify_buffer_size(bufhndl, noflines)
  638.  
  639. defproc verify_buffer_size(bufhndl, noflines)
  640.    orig_lines = ltoa(peek(bufhndl,28,4),10)
  641.    if orig_lines <> noflines & orig_lines then  -- If 0, assume never set.
  642.       display -4
  643.       sayerror ONLY__MSG noflines LINES_OF__MSG orig_lines RECOVERED__MSG
  644.       display 4
  645.    endif
  646.  
  647. defc clipview =
  648.    if not clipcheck(format) then
  649.       sayerror CLIPBOARD_ERROR__MSG
  650.       return
  651.    endif
  652.    if format<>256 then                 -- no text in clipboard
  653.       sayerror CLIPBOARD_EMPTY__MSG
  654.       return
  655.    endif
  656.    "open 'paste C' 'postme clipview2'"
  657.  
  658. defc clipview2 =
  659.    if .filename=UNNAMED_FILE_NAME then
  660.       .filename=CLIPBOARD_VIEW_NAME
  661.       .autosave = 0
  662.       .modify = 0
  663.       call browse(1)
  664.    endif
  665.  
  666. defproc clipcheck(var format)  -- Returns error code; if OK, sets FORMAT
  667. compile if EPM32
  668.    hab=gethwndc(0)                         -- get EPM's anchorblock
  669.    format = \0\0\0\0                       -- (reserve four bytes)
  670.    rc=dynalink32('PMWIN',                   -- call PM function to
  671.                  '#807',   -- look at the data in the cb
  672.                  hab              ||         -- anchor block
  673.                  atol(1)          ||         -- data format ( TEXT )
  674.                  address(format), 4)
  675. --   format = ltoa(format,10)                -- Convert format to ASCII
  676.    format = 1024
  677. compile else
  678.    hab=gethwnd(0)                          -- get EPM's anchorblock
  679.    format = \0\0                           -- (reserve two bytes)
  680.    rc=dynalink('PMWIN',                    -- call PM function to
  681.                'WINQUERYCLIPBRDFMTINFO',   -- look at the data in the cb
  682.                hab              ||         -- anchor block
  683.                atoi(1)          ||         -- data format ( TEXT )
  684.                address(format))
  685. --   format = itoa(format,10)                -- Convert format to ASCII
  686.    format = 256
  687. compile endif
  688.    return rc
  689.  
  690. compile if EVERSION >= 5.50
  691. defc insert_text_file
  692.    universal default_edit_options
  693.    get_file = strip(arg(1))
  694.    if get_file='' then sayerror NO_FILENAME__MSG 'GET'; return; endif
  695.    if pos(argsep,get_file) then
  696.       sayerror INVALID_OPTION__MSG
  697.       return
  698.    endif
  699.    getfileid fileid
  700.    s_last=.last
  701.    display -1
  702.    'e /q /d' get_file
  703.    editrc=rc
  704.    getfileid gfileid
  705.    if editrc=sayerror('New file') | not .last then
  706.       'q'
  707.       display 1
  708.       if editrc= -2 | not .last then  -- -2 = sayerror('New file') then
  709.          sayerror FILE_NOT_FOUND__MSG':  'get_file
  710.       else
  711.          sayerror FILE_NOT_FOUND__MSG':  'get_file
  712.       endif
  713.       return
  714.    endif
  715.    if editrc & editrc<>-278 then  -- -278  sayerror('Lines truncated') then
  716.       display 1
  717.       sayerror editrc
  718.       stop
  719.    endif
  720.    call psave_mark(save_mark)
  721. compile if WANT_BOOKMARKS
  722.    if not .levelofattributesupport then
  723.       'loadattributes'
  724.    endif
  725. compile endif
  726.    get_file_attrib = .levelofattributesupport
  727.    setmark 1, .last, 1, length(textline(.last))+1, 3, gfileid  -- 3 = CHARG mark
  728.    activatefile fileid
  729.    rc=0
  730.    copy_mark
  731.    copy_rc=rc           -- Test for memory too full for copy_mark.
  732.    activatefile gfileid
  733.    'q'
  734.    parse value save_mark with s_firstline s_lastline s_firstcol s_lastcol s_mkfileid s_mt
  735.    if fileid=s_mkfileid then           -- May have to move the mark.
  736.       diff=fileid.last-s_last          -- (Adjustment for difference in size)
  737.       if fileid.line<s_firstline then s_firstline=s_firstline+diff; endif
  738.       if fileid.line<s_lastline then s_lastline=s_lastline+diff; endif
  739.    endif
  740.    call prestore_mark(s_firstline s_lastline s_firstcol s_lastcol s_mkfileid s_mt)
  741.    activatefile fileid
  742.    if get_file_attrib // 2 then
  743.       call attribute_on(1)  -- Colors flag
  744.    endif
  745.    if get_file_attrib % 4 - 2 * (get_file_attrib % 8) then
  746.       call attribute_on(4)  -- Mixed fonts flag
  747.    endif
  748.    if get_file_attrib % 8 - 2 * (get_file_attrib % 16) then
  749.       call attribute_on(8)  -- "Save attributes" flag
  750.    endif
  751.    display 1
  752.    if copy_rc & copy_rc<>-281 then
  753.       sayerror NOT_2_COPIES__MSG get_file
  754.    endif
  755. compile endif
  756.