home *** CD-ROM | disk | FTP | other *** search
/ AMIGA PD 1 / AMIGA-PD-1.iso / Programme_zum_Heft / Programmieren / Kurztests / ACE / Prgs / Library / OpenWindow.b < prev    next >
Text File  |  1994-09-18  |  14KB  |  262 lines

  1. {*
  2. ** This program was sent to me (via John Stiwinter) from Jeff Harris. 
  3. ** Thanks Jeff!
  4. **
  5. ** Note that if one were to rewrite the following - removing comments -
  6. ** using built-in ACE commands/functions, the whole thing would take about
  7. ** half a dozen lines of code. This should give you some idea of the work
  8. ** being done by ACE internally when you issue a command like WINDOW/SCREEN.
  9. *}
  10.  
  11. REM A very simple "Hello World" Program That Runs Under ACE to demonstrate the
  12. REM use of system calls in ACE.
  13. REM Ported to AmigaBasic and ACE by Jeffrey Harris from Example in Intuition 
  14. REM RKM.  This program is public domain.
  15. REM Note:  This Program uses BMAPS files for the AmigaDOS 1.3 Libraries!
  16. REM Compatibility with 2.0+ Libraries and BMAPS has not been tested and is 
  17. REM not guaranteed, although the program runs fine on AmigaDOS 3.0.
  18. REM The program runs from a shell, or from WB, but diagnostics are only 
  19. REM printed when run from a shell window.
  20. REM There are four ways of accessing structures for making system calls:
  21. REM The first is to do an include from a header file (#?.h), which has the
  22. REM structure predefined.
  23. REM Note:  the '#' on the following line is a preprocessor directive.  The
  24. REM '<' and '>' brackets around "intuition.h" tell the preprocessor to look
  25. REM in the aceinclude: directory.
  26. #include <intuition.h> 'include file for window and screen stuff
  27. REM The second way to access a structure is for a programmer to define it
  28. REM himself.
  29. REM Define the MsgPort structure we will need using a self-made STRUCT 
  30. REM definition (this definition is actually a system structure that comes 
  31. REM from the EXEC RKM).
  32. STRUCT MsgPort 
  33.    STRING   mp_Node SIZE 14 'this is actually a Node structure
  34.    BYTE     mp_Flags 
  35.    BYTE     mp_SigBit 
  36.    LONGINT  mp_SigTask '* (a pointer) to a Task structure
  37.    STRING   mp_MsgList SIZE 14 'this is actually a message linked list 
  38. END STRUCT 'structure
  39. REM To access system routines, we must first open the Libraries that contain 
  40. REM them.  The next four lines do that.  These are the libraries we will need
  41. REM for this program.
  42. LIBRARY "diskfont.library"
  43. LIBRARY "exec.library"
  44. LIBRARY "intuition.library"
  45. LIBRARY "graphics.library"
  46. REM Next, we must tell ACE which system routines we want out of those
  47. REM libraries.  It is more efficient during compiling to put those routines
  48. REM together that come from the same library.
  49. REM initialize function calls to intuition
  50. DECLARE FUNCTION OpenWindow&() LIBRARY
  51. DECLARE FUNCTION OpenScreen&() LIBRARY
  52. DECLARE FUNCTION CloseWindow() LIBRARY 'this function does not return a
  53. REM parameter, so the trailing '&' is not necessary.
  54. DECLARE FUNCTION CloseScreen() LIBRARY 'ditto
  55. REM initialize function calls to Exec
  56. DECLARE FUNCTION AllocMem&() LIBRARY
  57. DECLARE FUNCTION FreeMem() LIBRARY 'ditto
  58. REM since Wait() conflicts with an Amigabasic Reserved Work, the system call
  59. REM has been renamed xWait
  60. DECLARE FUNCTION xWait&() LIBRARY 
  61. REM initialize function calls to DiskFont Library
  62. DECLARE FUNCTION OpenDiskFont&() LIBRARY
  63. DECLARE FUNCTION CloseFont() LIBRARY 'does not return a parameter
  64. REM initialize function calls to Graphics Library
  65. DECLARE FUNCTION Text&() LIBRARY
  66. DECLARE FUNCTION Move&() LIBRARY
  67. REM Let's play it safe, and initialize our pointers; always a good practice!
  68. MyMem&=0 'this will be the pointer to our allocated memory
  69. MyScreen&=0 'this will be the pointer to our defined screen structure
  70. rp&=0 'pointer to window's rastport (for text and graphics stuff)
  71. TF&=0 'pointer to our TextFont structure
  72. REM since the next two pointers directly access defined structures, we
  73. REM DECLARE them, as shown; the '*' in front of the pointer signifies that 
  74. REM the system will allocate the memory for the structure and initialize it 
  75. REM later.
  76. DECLARE STRUCT MsgPort *MyUP 'used to wait on a closewindow gadget click
  77. DECLARE STRUCT WindowStruct *MyWindow 'the pointer to our window structure
  78. REM a good programming practice is to provide a short main routine, and put
  79. REM the job of doing various things in subroutines or subprograms, which 
  80. REM makes the program very structured, modular, and easy to follow.
  81. REM Labels always have a trailing colon; the 'Main:' is not needed, but 
  82. REM provides clarity.
  83. Main: 
  84. gosub GetMem 'the memory allocation subroutine
  85. REM Note how the IF-THEN statements keep the program in check; an error 
  86. REM returned by one subroutine could cause a system crash in the next if we 
  87. REM did not provide for it.
  88. IF MyMem&<>0 THEN GOSUB ScrnSetup 'the screen setup and display subroutine
  89. IF MyScreen&<>0 THEN GOSUB WinSetup 'the window setup and display subroutine
  90. IF MyWindow<>0 THEN GOSUB WaitSig 'subroutine to wait on a close-window 
  91. REM gadget mouse click
  92. GOSUB CleanUp 'cleans up the program after an error or that mouse click
  93. END 'terminates the program; very important!  Otherwise, the program runs 
  94. REM right through the subroutines again, often with disasterous results!
  95. GetMem:
  96. REM 'Before' has to be a long integer because the value it returns could be
  97. REM larger than 65,000; hence the trailing '&'
  98. Before&=FRE(-1) 'check the total system free memory before we start 
  99. REM allocating it; used for checking that all the memory we allocated is 
  100. REM freed at the end of the program.  Note that since the program has started,
  101. REM and the system has to allocate it some memory to load, the memory
  102. REM displayed by workbench may not be the same as displayed here.
  103. PRINT "Memory Before Allocations is ";Before&
  104. REM To allocate memory using AllocMem&(), we need to tell it what we need...
  105. MemFlags&=SHL(1,16)+2 'Clear Mem Block, CHIP Mem (for INTUITION AND GRAPHICS
  106. REM stuff) and how much.  One hundred twenty bytes is sufficient for our
  107. REM needs here.  Note 120 must be represented as a long integer:  120&.
  108. REM Now, make the system call to allocate the needed memory; note that instead,
  109. REM we could have used the equivalent ACE Command:  MyMem&=Alloc(120,3)
  110. MyMem&=AllocMem&(120&,MemFlags&) 'Allocate 120 Bytes of Memory
  111. REM AllocMem&() returns the pointer to our memory, or zero if it could not
  112. REM allocate any memory.
  113. IF MyMem&=0 THEN
  114.    PRINT "Insufficient Memory"
  115. ELSE 
  116.    PRINT "My memory is located at ";MyMem&
  117.    REM now determine how much memory is free, and show; difference should equal 
  118.    REM what we asked for.
  119.    After&=FRE(-1)
  120.    PRINT "Memory After is Allocation is ";After&
  121.    PRINT "Memory Has Been Reduced by ";After& - Before&
  122. END IF
  123. RETURN 'completed what we need to in this routine; go back to calling routine
  124. ScrnSetup:
  125. REM First thing we want to do (but optional) is to select the screen font; 
  126. REM to do that, we set up TextAttr Structure using the third method of
  127. REM creating a structure:  using an array, which we must DIMension before use
  128. DIM TextAttr&(1) 'use long words for array; it is important that we align the 
  129. REM infomation properly; the '(1)' signifies that we need only two array
  130. REM elements.
  131. Myfont$="garnet.font" 'decide on a font; needs to be in fonts: directory
  132. REM The first variable in the structure is a pointer to the string with the
  133. REM font name; we pass that address using the SADD function for strings.
  134. TextAttr&(0)=SADD(Myfont$) 'pointer to our Font in TextAttr Structure
  135. REM the second variable are the flags that tell us about the font: point size
  136. REM is a word-sized variable, which resides in the upper word of the long word
  137. REM TextAttr&(1); got that?  Next comes style attributes in the next byte, and
  138. REM finally any flags in the lowest byte of that long word.  Graphically:
  139. REM bit:     0 (LSB)        7             15             23             31(MSB)
  140. REM                     point size              style          flags
  141. REM                  <------- increasing memory address
  142. TextAttr&(1)=SHL(9,16)+66 'flags for font - designed (not scalable), 
  143. REM diskbased (that's the 66 part), normal attributes (for style = 0), 
  144. REM 9 Point font.
  145. REM Note that it is not really necessary to actually open the font, as the
  146. REM screen statement sets the default font by using the TextAttr structure
  147. REM directly.
  148. REM However, with the OpenDiskFont call, we could have set up another
  149. REM TextAttr structure, called OpenDiskFont() and SetFont() and changed to a
  150. REM different font for our window text.
  151. TF&=OpenDiskFont&(@TextAttr&(0)) 'Open the normal attribute, 9 point Garnet Font
  152. IF TF&<>0 THEN
  153.         PRINT "Address for TextFont is ";TF&
  154. ELSE 
  155.         PRINT "Requested Font Open Failed"
  156.         REM will fail if font is not in Fonts: or Diskfont.library is not in
  157.         REM libs:
  158. END IF
  159. REM Set Up Screen Structure
  160. REM The fourth way of setting up a structure in memory is to allocate some
  161. REM memory, as we have done, and poke the data into that allocated memory.
  162. REM WARNING!  Make sure you know what you are doing!  Poking into unallocated
  163. REM memory, or beyond what you have allocated, can cause a system crash, as
  164. REM can putting inappropriate values in memory for a particular structure
  165. REM element, or placing them inappropriately (ie, wrong memory location, or
  166. REM wrong offset within a word or longword).
  167. REM To set up a screen structure, poke the required information into the
  168. REM memory locations as shown.  This information comes from the Intuition RKM;
  169. REM the 2.0 autodoc manual shows structure offsets, which makes doing this
  170. REM MUCH easier.  Some values are byte or word length, and so must be shifted
  171. REM 8, 16, or 24 bits to put them in the right location.  Memory mapping for
  172. REM byte and word values (16 bits) is the same as for arrays discussed above.
  173. REM What each value represents is shown in a comment after each line.
  174. POKEL MyMem&,SHL(20,16)+20 'left edge, top edge
  175. POKEL MyMem&+4,SHL(320,16)+200 'width, height
  176. POKEW MyMem&+8,4 'depth; note that poking a byte (POKE) or word (POKEW) can
  177. REM save having to make an offset, but takes more POKEs overall.
  178. POKEW MyMem&+10,SHL(21,8)+14 'Detail,block Pen (No View Modes Set)
  179. POKEW MyMem&+14,15 'Custom Screen
  180. POKEL MyMem&+16,@TextAttr&(0) 'Default Font; note how we pass the address of
  181. REM our TextAttr structure?
  182. Title$="A Simple Screen"
  183. POKEL MyMem&+20,SADD(Title$) 'Default Title for This Screen
  184. REM all the data for our screen is defined; now make the call to open it
  185. MyScreen&=OpenScreen&(MyMem&) 'open the screen
  186. IF MyScreen&=0 THEN 'MyScreen& will remain 0 if screen couldn't be opened
  187.    PRINT "Open Screen Failed"
  188. ELSE 'otherwise we will see a screen pop open before our very eyes!
  189.    PRINT "Screen Pointer is ";MyScreen& 'address to Screen structure
  190. END IF
  191. RETURN 'finished playing with the screen
  192. WinSetup:
  193. REM Time to set up a NewWindow Structure.
  194. REM In general, we follow the same procedure as setting up a new screen, but
  195. REM some of the parameters are different.
  196. POKEL MyMem&+60,SHL(20,16)+20 'left edge,top edge
  197. POKEL MyMem&+64,SHL(300,16)+100 'Width,height
  198. POKEW MyMem&+68,SHL(23,8)+5 'Detail,block Pen
  199. POKEL MyMem&+70,SHL(1,9) 'IDCMP Flags; in this case, notify us user clicks the
  200. REM CloseWindow gadget.
  201. POKEL MyMem&+74,SHL(1,12)+10 'Window Flags and Settings - Smart_Refresh,
  202. REM Activate Window, give us a Dragbar and CloseWindow Gadget, please!
  203. Title$="A Simple Window"
  204. POKEL MyMem&+86,SADD(Title$) 'Pointer to Window Title
  205. POKEL MyMem&+90,MyScreen& 'Pointer to screen for this window (this is only
  206. REM needed for a custom screen, as we are using in this example).
  207. POKEW MyMem&+106,15 'Value for a Screen Type that Corresponds to our screen -
  208. REM in this case, a custom screen (as opposed to the Workbench screen).
  209. REM Now, since we previously defined the Window Structure by #including    
  210. REM intuition.h, and DECLARED MyWindow to be a pointer to a window structure,
  211. REM we can now link a specific address to that pointer by using it as the
  212. REM return value for our open window call;  NOTE that the address passed to
  213. REM the OpenWindow call is the STARTING address of where we started POKING
  214. REM the NewWindow data into our allocated memory (this is true for any 
  215. REM structure):
  216. MyWindow=OpenWindow&(MyMem&+60)
  217. IF MyWindow=0 THEN 'MyWindow will remain 0 if window couldn't be opened
  218.    PRINT "Open Failed"
  219. ELSE 'otherwise, a new window will pop open on the screen before our eyes!
  220.    PRINT "Window Pointer is ";MyWindow
  221. END IF
  222. REM Now PRINT Some Text to demonstrate what we can do.
  223. Tx1$="Hello World!" 'The text to print.
  224. REM since we have explicitly used a structure, we can access it's elements
  225. REM directly as follows; in this case, we want the address of the RastPort.
  226. rp&=MyWindow->RPort 'beats rp&=PEEKL(MyWindow+50&), doesn't it?
  227. CALL Move(rp&,100&,60&) 'Move the Cursor within the window to position 100
  228. REM pixels to the left of the current position, and 60 pixels down.
  229. ER1=Text&(rp&,SADD(Tx1$),LEN(Tx1$)) 'Put our text in the window
  230. RETURN 'finished with window and text stuff
  231. WaitSig: 'Here's we we sleep until the User clicks on the close gadget
  232. REM the next two lines can be translated as "wait until a special signal 
  233. REM (mp_SigBit) arrives in the msgport (UserPort) of the window (MyWindow)"
  234. MyUP = MyWindow->UserPort 'need to access the address of our MsgPort for the
  235. REM window; note how again, we make use of an explicit structure.
  236. REM NOTE:  In general, one would have to check not only the bit, but also the
  237. REM specific msg that arrived in the MsgPort, since ANY message will awaken
  238. REM our task.  In this case, we have defined only one event (via the IDCMP
  239. REM flag in the NewWindow Structure above) which gets reported to our task,
  240. REM so we can be sure if we get a message, it's a closewindow click!
  241. Call xWait&(SHL(1,MyUP->mp_SigBit)) 'this actually puts our task to sleep
  242. PRINT "Sig Value = ";MyUP->mp_SigBit
  243. RETURN 'got the closewindow click; let's go back.
  244. CleanUp: 'Come Here on Error or after click on window gadget
  245. REM General Rules:  Close any resources opened (libraries, fonts, devices);
  246. REM Close in reverse order of opening.
  247. REM Note that these MUST be done in the order listed.
  248. IF MyWindow<>0 THEN CALL CloseWindow(MyWindow) 'Close the window, if opened
  249. IF MyScreen&<>0 THEN CALL CloseScreen(MyScreen&) 'Close the screen, if opened
  250. IF MyMem&<>0 THEN
  251.    IF TF&<>0 THEN CALL CloseFont(TF&) 'Close the font we opened
  252.    CALL FreeMem(MyMem&,120&) 'Give our memory back to the system
  253. END IF
  254. LIBRARY CLOSE 'Close all the libraries
  255. After&=FRE(-1)
  256. PRINT "Memory After Cleaning Up is ";After&
  257. PRINT "Memory Has Been Reduced by ";After& - Before& 'just a check; should be 
  258. REM 0.
  259. REM NOTE:  May be non-zero if system opened fonts, or other tasks have
  260. REM allocated memory while program is running.
  261. RETURN 'finished here!
  262.