lippin@ragu.berkeley.edu (The Apathist) (03/18/88)
Recently dplatt@coherent.com (Dave Platt) said: >Apple has apparently changed the MDEF so that it can recover gracefully >if it can't get a pixmap big enough to save the screen pixels; it >simply displays the menu without saving the pixels, and [when the user >releases the mouse button or moves to a different menu] erases the menu >rectangle to black and tells QuickDraw to invalidate the rectangle; >the application(s) that have windows intersecting the invalidated >rectangle are given window-update events, and can then redraw the >erased data. This causes a problem for me. Since there are so many ways for out-of-memory problems to screw up the toolbox, I've responded by writing a growzone function which, when it can't scrounge memory, will unload most segments, put up an alert, and then longjmp back into the main event loop. But this makes some menu choices fail even when MenuSelect could get by without the memory. What I want is a way to tell if a memory request is vital or not. I can write this into my side of the code, but I know of no way to test this when it's a toolbox call that needs the memory. Is there one? Will there be one eventually? (This is all grungy stuff that would be better handled by the OS anyway, I say.) --Tom Lippincott ..ucbvax!bosco!lippin "Those who understand will require no further explanation." --Saul Bellow, _Henderson the Rain King_
stew@endor.harvard.edu (Stew Rubenstein) (03/21/88)
In article <7786@agate.BERKELEY.EDU> lippin@ragu.UUCP (Tom Lippincott, ..ucbvax!bosco!lippin) writes: >Recently dplatt@coherent.com (Dave Platt) said: >>Apple has apparently changed the MDEF so that it can recover gracefully >>if it can't get a pixmap big enough to save the screen pixels; > >This causes a problem for me. Since there are so many ways for >out-of-memory problems to screw up the toolbox, I've responded by >writing a growzone function which, when it can't scrounge memory, will >unload most segments, put up an alert, and then longjmp back into the >main event loop. But this makes some menu choices fail even when >MenuSelect could get by without the memory. > >What I want is a way to tell if a memory request is vital or not. I >can write this into my side of the code, but I know of no way to test >this when it's a toolbox call that needs the memory. Is there one? >Will there be one eventually? (This is all grungy stuff that would be >better handled by the OS anyway, I say.) Low memory handling on the Mac is a bitch. There isn't any way to know when a memory request is critical, except to know what the toolbox needs the memory for. You have to assume that any request is critical. This is not far from the truth - memory allocation failures are handled very poorly by the toolbox. In my apps, I have routines Critical() and NonCritical(), which clear and set a flag checked by the growzone function. Then I have: INT32 MyMenuSelect(thePoint) Point thePoint; { INT32 result; NonCritical(); saveGhost = GhostWindow; /* MenuSelect will not update properly */ GhostWindow = 0; /* if you use GhostWindow. */ result = MenuSelect(thePoint); GhostWindow = saveGhost; Critical(); return result; } I also have a NewHandleNC() which I use for noncritical memory allocations in my own code. Another useful trick is to allocate a couple of buffers at the start of your program so that you have something to release when the growzone proc is called. Finally, it's important to preflight every memory request that you can. For example, before you call a routine in another segment, do a GetResource on the right CODE segment and check to see it succeeds. A failure to load a CODE segment causes an immediate system error. The GetResource won't waste much time, but you have to identify all the intersegment calls and have some way of telling what segment it's in. In MPW it's easy because it names the resources. For example: if (PreFlightCall(SEG_RotateFrob)) { RotateFrob(); UnloadSeg(RotateFrobox); } else { Alert (ALRT_notEnoughMemToRotateFrob, (FilterProc) 0); } It's especially hard to preflight QuickDraw region operations. I assume that an upper bound on the size of a region is proportional to the area of the bounding rectangle times an empirically derived fudge factor related to the likely complexity of the region. You can also use MapRgn to do the operation on a scaled-down region first, as suggested in Inside Macintosh, but I find this too time consuming for most purposes. Stew Rubenstein Cambridge Scientific Computing, Inc. UUCPnet: seismo!harvard!rubenstein CompuServe: 76525,421 Internet: rubenstein@harvard.harvard.edu MCIMail: CSC
jv0l+@andrew.cmu.edu (Justin Chris Vallon) (03/31/88)
I don't know if this is an actual bug in QuickerGraf, but the Menu-Manager is quite smart when drawing menus. If the MenuManager cannot allocate enough memory to save the image of the screen behind the menu being drawn, it erases it, and posts an Update event. The Update event tells the application that some parts of some windows are not drawn (in layman's terms :-) Making some crude calculations, the file/apple menu using Suitcase could be the length of the entire screen, which could be 10 inches, and about 2 1/2 inches wide, gives about: 175 pixels across x 700 pixels x 1 byte/pixel (8-bit mode) = 122.5K (!) Running under multi-finder, the Finder has a 160K partition, with about 40K free (taken from my About Finder... window). Needless to say, the MenuManager cannot allocate enough memory to save the screen image under the menu. So, it does the next best thing: erase the background and post and update event. I have seen this happen before when testing my own programs under low memory conditions, and on a Mac II. The erased windows were always re- drawn when I let go of the menu... are your windows being redrawn? -Justin