home *** CD-ROM | disk | FTP | other *** search
/ The Datafile PD-CD 3 / PDCD_3.iso / pocketbk / developmen / lpcs / LPASTE.TXT < prev    next >
Text File  |  1994-05-11  |  9KB  |  190 lines

  1. Implementing Link Paste in OPL
  2. Notes prepared by Tom Dolbilin March 26, 1994.
  3. Revision May 11, 1994.
  4.  
  5. Link Paste method is used for bringing data from one application
  6. to another. During this process the application that serves the
  7. data acts as a Link Paste Server (LPS) and the application that
  8. receives the data acts as a Link Paste Client (LPC). In general,
  9. applications may support only one of these modes, but the support
  10. for both is more common (Data, Word, Sheet and Agenda are the
  11. examples).
  12.  
  13. Notes on Link Paste Server example (LPS.OPL)
  14. There can be only one active LPS on the system at any one time.
  15. In order to become one, the application has to register with the
  16. Window Server. Normally this is done only if the application has
  17. some of its information highlighted at the time when it is
  18. switched to background. As soon as it registers as the LPS, it
  19. should be ready to receive a message from a LPC that wants to
  20. copy over the data.
  21.  
  22. Initialization
  23. One of the first things to do is to initialize messaging with the
  24. MessInit call:
  25.  
  26. ret%=call($83,$404,0,0,0,0)
  27. Here the second parameter, $404, is interpreted as 4*$100+4 where
  28. the first 4 is number of bytes to allocate for the message
  29. arguments (per message). In the example these are two words arg1%
  30. and arg2%. The second 4 is the number of message slots to
  31. allocate for queuing.
  32. Next we need the Window Server process ID. Note that in this
  33. particular case there is no need to add the terminating zero to
  34. name$, because it has just been declared and initialized:
  35.  
  36. name$="SYS$WSRV.*"
  37. wsrvPid%=call($188,addr(name$)+1)
  38. Now it is time to queue the console event and message reception.
  39. Both are asynchronous with status words kStat% and mStat%
  40. respectively:
  41.  
  42. ioa(-2,14,kStat%,event%(1),#0)
  43. call($183,addr(pM%),0,0,0,addr(mStat%)) rem
  44. MessReceiveAsynchronous
  45.  
  46. Main event loop
  47. In the main loop we wait for an event to happen. When it happens,
  48. we can find out what it was by checking the values of the status
  49. words. If mStat%<>-46 then we have received a message. If
  50. kStat%<>-46 then either a key has been pressed or a system event
  51. has occurred.
  52. We are only interested in two types of messages:
  53. $21  TY_LINKSV_STEP      sets the beginning of a stage in the
  54. linking process
  55. $22  TY_LINKSV_DEATH     sent to us if our LPC terminates
  56. When a message is received, its type and the two arguments are
  57. read from the message structure located at pM%:
  58.  
  59. mtype%=peekw(pM%+4)
  60. arg1%=peekw(pM%+8)
  61. arg2%=peekw(pM%+10)
  62. The meaning of the arguments is message-dependent. In the case of
  63. a TY_LINKSV_STEP message, it is also stage-dependent. The very
  64. first stage in the linking process is the initial request of a
  65. LPC. This is when we register the LPC as our client and find out
  66. which formats it supports. The rest of the stages are technically
  67. identical and the number of them depends of the amount of
  68. information to be transferred and the size of the temporary
  69. buffer it is going through.
  70.  
  71. The first stage in linking
  72. We know if this is the first request because clntPid% is NULL. At
  73. this time clntPid% is set to the process ID of our LPC, which can
  74. be read from the message structure:
  75.  
  76. clntPid%=peekw(pM%+6)
  77. However, we only do this if we support the format requested by
  78. the LPC. The format is a long integer that is stored across two
  79. words–the message arguments arg1% and arg2%:
  80.  
  81. fmt&=peekl(addr(arg1%))
  82. fmt& can be a combination of any of the possible format values
  83. listed below:
  84. $00                  DF_LINK_NATIVE application-dependent native
  85.                      format
  86. $02                  DF_LINK_TEXT   NULL paragraph delimiters
  87.                      are not transmitted, but different text
  88.                      buffers should be treated as separate
  89.                      paragraphs
  90. $04                  DF_LINK_TABTEXT     same as DF_LINK_TEXT,
  91.                      but can include tab characters
  92. $10                  DF_LINK_PARAS  the server can include NULL
  93.                      paragraph delimiters and the transmitted
  94.                      buffers of text are not treated as separate
  95.                      paragraphs
  96.  
  97. The subsequent stage(s) in linking
  98. Non-zero clntPid% means that this is a subsequent stage when a
  99. chunk of data should be transferred from the server to the
  100. client. The two message arguments have the following meaning:
  101. arg1%     the address in the client segment where the data buffer
  102.           should be copied to. NULL signifies the end of the
  103.           transfer.
  104. arg2%     the size of the buffer to be copied. Normally, it
  105.           should not exceed 256 bytes unless a native link-paste
  106.           format is used.
  107. If the amount of data to be sent must not exceed the size of the
  108. buffer. If it does, then it will have to be broken up in chunks
  109. and transferred in more than one step. After the length of the
  110. chunk is calculated, the buffer is copied to the client process
  111. segment by using the ProcCopyToById call:
  112.  
  113. ret%=min(len(buf$),arg2%)
  114. call($92,clntPid%,ret%,0,addr(buf$)+1,arg1%)
  115. The ret% value is important because it will have to be included
  116. in the MessFree call:
  117.  
  118. call($783,pM%,ret%)
  119. The example only shows how to transfer a single buffer of data.
  120. However, it can be easily modified to allow for transfer of
  121. multiple buffers. Just keep the state% variable set to NULL until
  122. the last buffer has been transferred.
  123.  
  124. Becoming the server
  125. None of the above will happen until we register ourselves as the
  126. LPS. We do this in response to the system event $402 (send to
  127. background) by informing the Window Server with a
  128. MessSendReceiveWithWait call:
  129.  
  130. fmt&=$16 rem Prepared to render in any format
  131. ret%=call($683,wsrvPid%,3,0,addr(fmt&))
  132. The third parameter 3 is the SY_LINK_SERVER constant, the type of
  133. message to send.
  134.  
  135. Notes on Link Paste Client example (LPC.OPL)
  136.  
  137. Initialization
  138. As in the case with LPS, we need to get the process ID of the
  139. Window Server:
  140.  
  141. name$="SYS$WSRV.*"
  142. wsrvPid%=call($188,addr(name$)+1)
  143. We also need to get the handle of our I/O semaphore to be able to
  144. release the signals we are not interested in. The semaphore
  145. handle is stored in the E_PROC structure associated with our
  146. process. This structure is found in the system kernel's segment
  147. at address calculated from our own process ID, (ourPid% and
  148. $fff). Furthermore, the semaphore handle is stored in bytes 34
  149. and 35 of the structure. We can use the GenGetOsData call to
  150. retrieve these 2 bytes:
  151.  
  152. call($78b,0,2,0,(call($88) and $fff)+33,addr(ioSem%))
  153. Next, we use the MessSendReceiveWithWait call to ask the Window
  154. Server to give us the process ID of the LPS, if there is one. At
  155. the same time we pass the pointer to the address of fmt& so we
  156. can find out which formats are supported by the LPS:
  157.  
  158. pfmt%=addr(fmt&)
  159. srvPid%=call($683,wsrvPid%,4,0,addr(pfmt%))
  160. Getting the name of the LPS is unnecessary and the code does this
  161. only to display it in the title of the dialog, which lists all
  162. formats supported by the LPS and lets the user to select which of
  163. them to use. Again, this is done for demonstration purposes. In
  164. practice, your application should pick the best format
  165. automatically. Note, that since the native format DF_LINK_NATIVE
  166. is 0, it is impossible to tell if it‹s available or even
  167. supported by the link-paste server. Use it only if you are sure
  168. that the LPS supports it. For example, the text editor mode of
  169. Word will crash if you request DF_LINK_NATIVE from it.
  170. When the dialog returns, the selected format should be sent to
  171. the LPS as a message argument. Technically it should be 4 bytes
  172. long and stored across both message arguments, but because in
  173. this example the format values are small, it is sufficient to
  174. assign it only to the first message argument w%(1).
  175.  
  176. Procedure talk%:(arg1%,arg2%)
  177. This procedure sends the TY_LINKSV_STEP ($21) message to the LPS
  178. and waits for the reply. The procedure parameters are the message
  179. arguments. The return value is the error. The chunks of data are
  180. being received one by one until an error is returned. EOF is
  181. returned when all the data has been transferred.
  182. One piece of code has been omitted from the LPC example