jmunkki@kampi.hut.fi (Juri Munkki) (08/09/89)
I just discovered that I had wasted several weeks hunting down a bug in my source code, when it actually wasn't there. The problem was that somehow the system was using grafports that didn't exist. I always use the sequence: GetPort(&saved); SetPort(someport); ... SetPort(saved); This means that when InitWindows sets the port to the window manager port, it usually remains that way for the rest of my program. I verified this with a debugger. I then proceeded to start with Suitcase II (v 1.2.2) enabled and the behavior changed. Whenever I opened a desk accessory, the port would change to that window. The problem is that when the desk accessory is closed, the port (thePort for you programmers) stays in that now defunct window. You might say that this does not matter, because everyone calls SetPort before doing any _drawing_. The problem arises when some programs create regions or pictures and just assume that it's fine to use any port (in a storm?). The Blast FKEY is a good example, since the source code was published in MacTutor. Even the window manager might do this, but I haven't checked this. This bug might affect any really well behaved application. Imagine my anger when I discovered that I follow all the apple guidelines and even a few of my own and that my software has a problem with desk accessories! The first fix that came to my mind was to change ports every time one of windows is activated or deactivated. This doesn't solve the problem when there are no windows open. Any bright suggestions? I don't want to call SetPort every time I go through the event loop, but I just might have to do that...Suitcase is too popular to be ignored. Please check your own source code. Even if you don't restore your grafports, it is possible (although highly unlikely) that your code will crash in some situations. I would really like to get some feedback on this. If you do not want to post, please feel free to mail me. (If jmunkki@hut.fi doesn't work, try mcvax!santra! jmunkki) _._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._ | Juri Munkki jmunkki@hut.fi jmunkki@fingate.bitnet I Want Ne | | Helsinki University of Technology Computing Centre My Own XT | ^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^
jmunkki@kampi.hut.fi (Juri Munkki) (08/09/89)
This is a followup to my original article. At that time I still hadn't thought of a reasonable fix to the problem. Here's what I decided to do: StartSetup(); /* This calls InitWindows among other things. */ GetPort(&WindowManagerPort); do /* my main event loop */ { /* The following line fixes a bug in Suitcase: */ if(thePort != WindowManagerPort) SetPort(WindowManagerPort); ... Can anyone think of a reason why this wouldn't work? I wanted to optimize things, so I use thePort instead of calling GetPort. Usually I avoid this kind programming, but this time I think it can't hurt to use a global. _._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._ | Juri Munkki jmunkki@hut.fi jmunkki@fingate.bitnet I Want Ne | | Helsinki University of Technology Computing Centre My Own XT | ^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^
mystone@caen.engin.umich.edu (Dean Yu) (08/09/89)
In article <24320@santra.UUCP> jmunkki@kampi.hut.fi (Juri Munkki) writes: >I just discovered that I had wasted several weeks hunting down a bug in >my source code, when it actually wasn't there. The problem was that somehow >the system was using grafports that didn't exist. > >I always use the sequence: > GetPort(&saved); > SetPort(someport); > ... > SetPort(saved); > >This means that when InitWindows sets the port to the window manager port, >it usually remains that way for the rest of my program. I verified this >with a debugger. > >I then proceeded to start with Suitcase II (v 1.2.2) enabled and the >behavior changed. Whenever I opened a desk accessory, the port would >change to that window. The problem is that when the desk accessory is >closed, the port (thePort for you programmers) stays in that now >defunct window. > This isn't a bug in Suitcase, but a problem with some DAs. It's fairly well known that some older DAs don't restore the grafPort when they close or get switched out. _______________________________________________________________________________ Dean Yu | E-mail: mystone@{sol,caen}.engin.umich.edu University of Michigan | Real-mail: Dean Yu Computer Aided Engineering Network | 909 Church St | Apt C ===================================| Ann Arbor, MI 48104 | Phone: Given on a need to know basis, and "I am the Merit Host. I speak for | only if you're going to offer me a the bitstream." (In other words, | job... these are my very own opinions; | my employer wants to have nothing |=========================================== to do with them, or me.) | This space available for rent -------------------------------------------------------------------------------
mystone@caen.engin.umich.edu (Dean Yu) (08/09/89)
In article <24321@santra.UUCP> jmunkki@kampi.hut.fi (Juri Munkki) writes: >This is a followup to my original article. At that time I still hadn't >thought of a reasonable fix to the problem. Here's what I decided to >do: > >StartSetup(); /* This calls InitWindows among other things. */ >GetPort(&WindowManagerPort); > >do /* my main event loop */ >{ /* The following line fixes a bug in Suitcase: */ > if(thePort != WindowManagerPort) SetPort(WindowManagerPort); >... > >Can anyone think of a reason why this wouldn't work? I wanted to optimize >things, so I use thePort instead of calling GetPort. Usually I avoid this >kind programming, but this time I think it can't hurt to use a global. > It works, but i wouldn't call it optimizing. If you're setting the port to the Window Manager port every time the current port isn't the Window Manager's port, you're going to have to set the port to a window's grafPort every time you want to do any drawing. If you're going to do that anyway, the conditional seems to be excess baggage. (And you shouldn't be drawing to the Window Manager port anyway, if you are...) _______________________________________________________________________________ Dean Yu | E-mail: mystone@{sol,caen}.engin.umich.edu University of Michigan | Real-mail: Dean Yu Computer Aided Engineering Network | 909 Church St | Apt C ===================================| Ann Arbor, MI 48104 | Phone: Given on a need to know basis, and "I am the Merit Host. I speak for | only if you're going to offer me a the bitstream." (In other words, | job... these are my very own opinions; | my employer wants to have nothing |=========================================== to do with them, or me.) | This space available for rent -------------------------------------------------------------------------------
earleh@eleazar.dartmouth.edu (Earle R. Horton) (08/10/89)
... >windows is activated or deactivated. This doesn't solve the problem when >there are no windows open. Any bright suggestions? I don't want to call >SetPort every time I go through the event loop, but I just might have to Do it. It's the paranoid way, and it's the only way to be sure some nasty little code-snippet doesn't ever change thePort behind your back. Earle R. Horton
jmunkki@kampi.hut.fi (Juri Munkki) (08/10/89)
In <44ed4fee.19c13@locust.engin.umich.edu> mystone@sol.engin.umich.edu writes: >In article <24321@santra.UUCP> jmunkki@kampi.hut.fi (Juri Munkki) writes: >>StartSetup(); /* This calls InitWindows among other things. */ >>GetPort(&WindowManagerPort); >> >>do /* my main event loop */ >>{ /* The following line fixes a bug in Suitcase: */ >> if(thePort != WindowManagerPort) SetPort(WindowManagerPort); >>... > > It works, but i wouldn't call it optimizing. If you're setting the port >to the Window Manager port every time the current port isn't the Window >Manager's port, you're going to have to set the port to a window's grafPort >every time you want to do any drawing. If you're going to do that anyway, the >conditional seems to be excess baggage. (And you shouldn't be drawing to the >Window Manager port anyway, if you are...) The SetPort only happens when a DA or Suitcase (or something else) changes thePort. My own routines always use GetPort/SetPort/Draw/SetPort. That's why the bug was causing me so much trouble (a crash/week). I'm not doing any drawing in the window manager port. I'm not even using the window manager port. I just set thePort to point to that so that some buggy DAs/FKEYs/... can have a grafport to play with (to create regions for example). My own program always calls SetPort before drawing anything. The alternative to the code above would have been to call SetPort every time through the event loop. Why do I have to call SetPort every time I want to draw something? If DAs can change thePort, then I can't rely that my port setting will remain when I call GetNextEvent/SystemTask. _._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._ | Juri Munkki jmunkki@hut.fi jmunkki@fingate.bitnet I Want Ne | | Helsinki University of Technology Computing Centre My Own XT | ^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^
dolf@janus.UUCP (Dolf Starreveld) (08/10/89)
jmunkki@kampi.hut.fi (Juri Munkki) writes: >I just discovered that I had wasted several weeks hunting down a bug in >my source code, when it actually wasn't there. The problem was that somehow >the system was using grafports that didn't exist. > .... Trimmed .... >I then proceeded to start with Suitcase II (v 1.2.2) enabled and the >behavior changed. Whenever I opened a desk accessory, the port would >change to that window. The problem is that when the desk accessory is >closed, the port (thePort for you programmers) stays in that now >defunct window. Correct, this could even happen before Suitcase ever existed, because not all DA programmers were doing what you are doing and restoring the original port on exit. I don't have the docs handy right now, but it says somewhere in IM-I that you should preserve the current port across calls to DAs (or was it in a Tech Note, I'm not sure, but this info is very old). The confusing thing is that IM also says that the desk manager preserves the current port for you, but it doesn't. > ... Trimmed ... As far as I can see, preserving "thePort" whenever you call desk accessories or anything else that might pop up windows in unexpected ways (read something that is beyond your own control), or might change the current port, will solve your problems. --dolf -- Dolf Starreveld Phone: +31 20 592 5056/+31 20 592 5022, TELEX: 10262 HEF NL EMAIL: dolf@fwi.uva.nl (dolf%fwi.uva.nl@hp4nl.nluug.nl) SNAIL: Dept. of Math. and Computing Science, University of Amsterdam, Kruislaan 409, NL-1098 SJ Amsterdam, The Netherlands